具有ios界面元素的强弱修饰符

时间:2013-02-07 21:47:02

标签: ios pointers uikit weak-references strong-references

在我的项目中,我不使用Interface Builder,我注意到一件我不知道如何解释的事情。然而。所以,到了这一点。当我们在控制器中使用IB并定义用户界面的元素(如UILabel或UIButton)时,我们使用这个丑陋的前缀IBOutlet和一个“弱”修饰符。这就像音乐一样。但是当我们决定不使用IB并从代码中定义整个用户界面时,它就不起作用了。

假设我想将UILabel添加到控制器(使用IB)。我会有类似的东西i * .h文件:

@property (nonatomic, weak) IBOutlet UILabel * label;

我不需要在* .m文件中做更多的事情。但是,如果我删除* .xib文件并尝试设置我的UILabel,例如,init方法之一,如下所示:

self.label = [[UILabel alloc] initWithFrame:CGRectMake(0,0,100,20)];
self.label.text = @"some text";
[self.view addSubview:self.label];

直到我将* .h文件更改为此内容后才能生效:

@property (nonatomic, strong) UILabel * label;

现在,我知道弱与强之间的区别,但我不知道为什么我们在使用IB时可以使用弱的ui元素?有些东西必须保持对这些元素的强烈指示,对吧?但是什么?在第二种情况下,它是控制器,但我不明白它在第一种情况下的表现。

3 个答案:

答案 0 :(得分:4)

Interface Builder为IBOutlet创建弱引用的原因如下:

IB知道视图由其superview保留。因此,视图树中的任何对象都不需要除了根对象之外还有强引用。视图控制器将此强引用保留在其主view属性中。

现在当卸载视图时(至少在iOS 5中),UIViewController的view属性设置为nil,释放主视图。如果此超级视图的子视图的IBOutlets是强引用,则它们将视图层次结构的一部分保留在内存中。这是不需要的(并且在访问这些孤立的视图时可能会导致混淆)。

答案 1 :(得分:3)

  

必须对这些元素保持强烈的指示,对吧?但是什么?

正确,您必须至少有一个对象的强引用才能存在。你只需要对UI的根级对象有一个强引用,这下面的任何东西都可能很弱(因为父对象将拥有它们的子级)。与其文件所有者协调的.xib文件将为您完成此操作。

this document on the workings of xib files。具体来说,这个snippit:

  

您通常需要对顶级对象的强引用,以确保它们不会被释放;你不需要强烈引用图中较低的对象,因为它们是由父母拥有的,你应该尽量减少创建强引用周期的风险。

     

从实际角度来看,在iOS和OS X中,出口应该被定义为声明的属性。 Outlets通常应该是弱的,除了那些从File的Owner到nib文件中的顶级对象(或者,在iOS中,故事板场景)应该很强。因此,您创建的插座通常应该很弱

答案 2 :(得分:1)

尽管已经接受了答案,但可以在代码

中实现这一点
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0,0,100,20)]; // strong ref
label.text = @"some text";
[self.view addSubview:label]; // strong ref from superview
self.label = label; // weak ref
// Now you can do `label = nil;`

这是从XIB加载时的要点。将label 分配给您的弱房产时,{{1}} 已经具有超级视图