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

paw*_*isz 6 pointers weak-references uikit ios strong-references

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

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

@property (nonatomic, weak) IBOutlet UILabel * label;
Run Code Online (Sandbox Code Playgroud)

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

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

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

@property (nonatomic, strong) UILabel * label;
Run Code Online (Sandbox Code Playgroud)

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

Nik*_*uhe 5

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

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

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


WDU*_*DUK 4

\n

某些东西必须保留指向这些元素的强指针,对吗?但什么?

\n
\n

正确的,您必须至少有 1 个对对象的强引用才能使其存在。您只需要对 UI 的根级别对象有一个强引用,低于此的任何内容都可以是弱引用(因为父对象将拥有其子对象)。文件.xib与其文件所有者协调会为您完成此操作。

\n

请参阅此文档了解文件的工作原理xib。具体来说,这个片段:

\n
\n

您通常需要对顶级对象进行强引用,以确保它们不会被释放;您不需要对图中下方的对象进行强引用,因为它们由其父级拥有,并且您应该最大限度地减少创建强引用循环的风险。

\n

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

\n
\n

  • 这不太正确。UINib 不拥有 Outlet,它们由视图拥有 - 视图对其子视图具有强引用。弱引用是在视图卸载时释放内存,这种情况不再发生,所以现在没有实际意义。 (2认同)