【问题标题】:Does IBOutlet imply __weak?IBOutlet 是否暗示 __weak?
【发布时间】:2012-04-25 03:03:50
【问题描述】:

刚开始使用 ARC。 Pre-ARC,我只是简单地声明我的出口,例如:IBOutlet UIButton *button; 所以我不保留它或任何东西。对于 ARC,不指定弱或强意味着强。

所以如果我在 ARC 下做同样的事情(即IBOutlet UIButton *button;),这是否意味着按钮是一个强参考?还是我必须明确将其定义为弱?

简而言之,IBOutlet 是否暗示__weak?

【问题讨论】:

    标签: objective-c ios cocoa-touch automatic-ref-counting


    【解决方案1】:

    IBOutlet这个词实际上定义为空:

    #define IBOutlet
    

    Xcode 只是在你的代码中使用这个词的存在来允许你在 Interface Builder 中建立连接。将变量或属性声明为IBOutlet

    IBOutlet UIButton * button;
    @property (...) IBOutlet UIButton * button;
    

    因此就 ARC 而言没有任何直接影响;它不会(尽管可以想象,它可以)翻译成__weak 或类似的东西。当编译器得到它时,这个词本身已经完全从你的源代码中消失了。

    另一方面,这个变量或属性是一个出口这一事实确实需要考虑内存管理的方式产生有意义的影响。 p>

    如您所说,ARC 下 IBOutlet UIButton * button; 等对象变量声明的隐式存储限定符是 __strong - 分配给该变量的任何对象都将被视为“拥有”。在 MRR 下,声明只是一个指针;分配 to 对分配对象的引用计数/所有权没有影响——它的行为方式与 assign 属性相同。* 因此,相同 ivar 声明的含义在两个管理系统之间会发生变化。

    xib 中的对象具有由视图层次结构形成的拥有/所有者关系;也就是说,父视图拥有它们的子视图。 xib 中的顶级视图由称为文件所有者的对象拥有。这种设置意味着,一般来说,您对 xib 中 顶级对象的出口应该是 weak(在 ARC 下)或 assign(如果是 MRR 下的属性)。他们不拥有关系;它们本质上是视图列表中的方便索引。这是Apple's recommendation

    ...您不需要对图中下方的对象进行强引用,因为它们归其父级所有,您应该尽量减少创建强引用循环的风险。

    [...]Outlets 通常应该是weak,除了从文件所有者到 nib 文件(或者,在 iOS 中,故事板场景)中的顶级对象应该是 strong。您创建的 Outlets 应该 [sic] 因此默认情况下通常是 weak...

    您的简单指针IBOutlets,正如我所解释的那样——出于内存管理的目的——就像weak 属性一样,**这意味着他们正在做正确的事情。在 ARC 下编译时,相同的声明可能是错误的

    总结:IBOutlet 不会翻译weak,但它确实改变了指针的含义。由于IBOutlet UIButton * button; 的默认内存管理语义从 MRR 下的“assign”变为 ARC 下的“owned”,并且由于IBOutlets 通常应该是非拥有的,IBOutlet 的存在确实暗示 指针应在 ARC 下声明为 __weak


    *与weak 属性类似——唯一的区别是当对象被释放时,weak 指针被设置为nil

    **auto-nil 部分除外。

    或者,真的,它应该是weak 属性。

    【讨论】:

    • 谢谢,现在清楚多了。但是我感到困惑的一件事是:即使我没有将 IBOutlet 明确定义为 __weak (在这种情况下它会很强大),ARC 不会处理它吗?只要没有保留周期(也没有),一切都会得到处理,不是吗?
    • ARC 将继续做它的工作,所以,是的,只要你避免保留循环,strongIBOutlet 也可以工作。
    【解决方案2】:

    不,IBOutlet 基本上是在编译代码时被剥离的。然而,它是 XCode 的助手,因此它可以知道什么是 InterfaceBuilderOutlet。

    基本上,这个词可以让你在 Interface Builder 中连接元素。

    默认情况下它仍然很强大(想象一下这个词不存在)。

    但是建议您将其设置为弱,因为一旦将某些东西连接到接口构建器,该接口将保持对其的强引用,因此具有双重强引用是没有意义的,特别是如果该元素是当接口被卸载时,并不意味着保持活动状态。

    阅读这个问题,这正是您正在寻找的:

    Should IBOutlets be strong or weak under ARC?

    【讨论】:

    • 我必须将我的 IBOutlet 声明为属性吗?
    • 不,你不需要,你可以将它们声明为实例变量,如果你在 MacOS 上这样做会有所不同,你可以在这里阅读更多信息:stackoverflow.com/questions/1221516/…
    • 好的,如果我将它们声明为实例变量,最好是这样:__weak IBOutlet UIButton *button,对吧?
    • 我认为你会遇到很多麻烦“__weak IBOutlet UIButton *button;”是正确的,如果您使用 arc 和 xcode 4.2,您应该只打开故事板并选择要引用的元素。然后在右上角点击编辑器(助手编辑器)的中间按钮。然后只需控制将按钮拖动到相应视图控制器的头文件中,天气您将其添加为强或弱 xcode 将负责其余部分。 (确保辅助编辑器设置为自动并选择了正确的标题)
    【解决方案3】:

    IBOutlet 关键字仅用于将对象与 Interface Builder 中的元素相关联。它与弱或强、ARC 或内存管理无关。

    【讨论】:

    • 这太荒谬了; IBOutlets 的内存管理需要像任何其他变量的管理一样考虑。
    • @JacquesCousteau 不是真的,仔细阅读他的答案,IBOutlet KEYWORD,与天气无关,属性将设置为强或弱。他说的是100%准确的。无论您决定如何管理该对象的内存。
    • @JacquesCousteau 并没有改变关键字本身并不暗示或影响任何特定的内存管理策略这一事实,这是这个问题和答案的重点。这个答案对这个问题是正确的。
    • @0xSina 因为当您将属性设置为 strong 时,它的引用计数会增加 1,如果您在视图消失时不这样做,则指针将丢失但对象将保留 +1 计数,因此你得到一个内存泄漏。
    • @0xSina 恐怕如果我继续在 cmets 上向您解释这一点,您会更加困惑。阅读本文的第 1 部分和第 2 部分:raywenderlich.com/5677/beginning-arc-in-ios-5-part-1 应该很清楚。
    猜你喜欢
    • 2016-04-05
    • 2018-03-07
    • 1970-01-01
    • 2019-09-23
    • 1970-01-01
    • 2011-03-17
    • 2012-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多