刚开始使用 ARC。Pre-ARC,我只是简单地声明我的出口,例如:IBOutlet UIButton *button;
所以我不保留它或任何东西。对于 ARC,不指定弱或强意味着强。
因此,如果我在 ARC(即IBOutlet UIButton *button;
)下做同样的事情,这是否意味着按钮是一个强参考?还是我必须明确将其定义为弱?
简而言之,IBOutlet 是否暗示__weak?
刚开始使用 ARC。Pre-ARC,我只是简单地声明我的出口,例如:IBOutlet UIButton *button;
所以我不保留它或任何东西。对于 ARC,不指定弱或强意味着强。
因此,如果我在 ARC(即IBOutlet UIButton *button;
)下做同样的事情,这是否意味着按钮是一个强参考?还是我必须明确将其定义为弱?
简而言之,IBOutlet 是否暗示__weak?
这个词IBOutlet
实际上被定义为无:
#define IBOutlet
Xcode 只是在你的代码中使用这个词的存在来允许你在 Interface Builder 中建立连接。将变量或属性声明为IBOutlet
:
IBOutlet UIButton * button;
@property (...) IBOutlet UIButton * button;
因此就 ARC 而言没有任何直接影响;它不会(尽管可以想象,它可以)转化为__weak
或类似的东西。当编译器得到它时,这个词本身已经完全从你的源代码中消失了。
另一方面,这个变量或属性是一个出口这一事实确实对您需要如何考虑内存管理产生了有意义的影响。
正如您所说,对象变量声明的隐式存储限定符(如IBOutlet UIButton * button;
在 ARC 下)是- 分配给该变量的任何对象都将被视为“拥有”。__strong
在 MRR 下,声明只是一个指针;分配给对分配对象的引用计数/所有权没有影响——它的作用与assign
属性相同。*因此,相同 ivar 声明的含义在两个管理系统之间发生了变化。
xib 中的对象具有由视图层次结构形成的拥有/所有者关系;也就是说,父视图拥有它们的子视图。xib 中的顶级视图由称为文件所有者的对象拥有。这种设置意味着,一般来说,您对 xib 中非顶级对象的出口应该是weak
(在 ARC 下)或assign
(如果是 MRR 下的属性)。他们不拥有关系;它们本质上是视图列表中的方便索引。这是苹果的建议:
...您不需要对图中较低的对象进行强引用,因为它们归其父对象所有,并且您应该将创建强引用循环的风险降至最低。
[...]Outlets 通常应该是
weak
,除了从 File's Owner 到 nib 文件(或者,在 iOS 中,故事板场景)中的顶级对象的那些应该是strong
. 您创建的网点应该 [原文如此] 因此通常weak
默认为...
IBOutlet
正如我所解释的,您的简单指针s 起作用——出于内存管理的目的——比如weak
属性,** 这意味着它们正在做正确的事情。在 ARC 下编译时,相同的声明可能会出错。
总而言之:IBOutlet
不会翻译成weak
,但它确实改变了指针的含义。由于默认的内存管理语义IBOutlet UIButton * button;
从 MRR 下的“分配”更改为 ARC 下的“拥有”,并且由于IBOutlet
s 通常应该是非拥有的,因此存在IBOutlet
确实意味着指针应该__weak
在 ARC 下声明。†</sup>
*与weak
属性类似——唯一的区别是weak
指针被设置为nil
对象被释放时。
**汽车零件除外nil
。
†</sup>或者,真的,它应该是一个weak
属性。
不,IBOutlet 基本上在代码编译时被剥离。然而,它是 XCode 的助手,因此它可以知道什么是 InterfaceBuilderOutlet。
基本上这个词可以让你在 Interface Builder 中连接元素。
默认情况下它仍然很强大(想象一下那个词不存在)。
但是,建议您将其设置为弱,因为一旦将某些内容连接到界面构建器,该界面将保持对其的强引用,因此具有双重强引用是没有意义的,特别是如果该元素不打算当接口被卸载时保持活动状态。
阅读这个问题,这正是您正在寻找的:
IBOutlet 关键字仅用于将对象与 Interface Builder 中的元素相关联。它与弱或强或 ARC 或内存管理无关。