【问题标题】:ARC - The meaning of __unsafe_unretained?ARC - __unsafe_unretained 的含义?
【发布时间】:2012-01-25 09:51:22
【问题描述】:

只是想确保我做对了:

  1. 我需要__unsafe_unretain 不属于我的对象吗?
  2. 如果对象是__unsafe_unretained,我是否需要在@property 中使用assign?这是否意味着该对象没有被保留,而只是引用我分配给的对象?
  3. 除了代表,我什么时候想使用它?
  4. 这是 ARC 的东西还是以前使用过?

【问题讨论】:

    标签: objective-c ios macos xcode4 automatic-ref-counting


    【解决方案1】:
    1. 不,您也可以将weak 用于您不拥有的对象。
    2. 不,您也可以在属性上使用unsafe_unretained
    3. 我的理解是 unsafe_unretained 项目就像 weak 一样,没有额外的安全性,当它们指向的项目被释放时清除它们(以及随之而来的开销)。
    4. 这完全是 ARC 的事情。

    【讨论】:

    • 实际上,奇怪的是,unsafe_unretained iVars 在运行时设置时的行为就像strong 一样,这让我相信unsafe_unretained 只是一个编译器提示,而weak 不是.更多信息在这里:stackoverflow.com/questions/11621028/…
    【解决方案2】:

    __unsafe_unretained 与 ARC 之前对象的默认存储相同。现在使用 ARC,默认值为 __strong,这意味着您可以引用它,直到您的引用超出范围。

    【讨论】:

      【解决方案3】:

      LLVM 编译器 3.0 引入了四个新的所有权限定符:__strong__autoreleasing__unsafe_unretained__weak。根据the specification,前三个甚至在 ARC 之外也可用。

      正如 Joshua 所指出的,默认情况下,ARC 下的所有指针都隐含为 __strong。这意味着当一个对象被分配给该指针时,只要该指针引用它,它就会被保留。这对大多数事情都很好,但它开辟了保留周期的可能性,正如我在回答 here 中所描述的那样。例如,如果您有一个对象包含另一个对象作为实例变量,但第二个对象作为其委托与第一个对象有强链接,则这两个对象将永远不会被释放。

      正是由于这个原因,存在__unsafe_unretained__weak 限定符。它们最常见的用途是委托,您可以使用weakunsafe_unretained 属性为该委托定义一个属性(assign 实际上是unsafe_unretained),然后通过将相应的实例变量标记为__weak__unsafe_unretained。这意味着委托实例变量仍将指向第一个对象,但不会导致该对象被保留,从而打破保留循环并允许释放两个对象。

      除了委托之外,这对于打破可能在您的代码中形成的任何其他保留周期很有用。有用的是,Leaks 工具现在包含一个 Cycles 视图,它以图形方式显示它在您的应用程序中发现的保留周期。

      __unsafe_unretained__weak 都阻止了对象的保留,但方式略有不同。对于__weak,指向对象的指针将在释放它指向的对象时转换为nil,这是非常安全的行为。顾名思义,__unsafe_unretained 将继续指向对象所在的内存,即使在对象被释放后也是如此。由于访问该已释放对象,这可能会导致崩溃。

      那你为什么要使用__unsafe_unretained?不幸的是,__weak 仅支持 iOS 5.0 和 Lion 作为部署目标。如果你想重新定位到 iOS 4.0 和 Snow Leopard,你必须使用 __unsafe_unretained 限定符,或者使用类似 Mike Ash 的 MAZeroingWeakRef

      【讨论】:

      • 当然__unsafe_unretained 可用于定义NSString 常量等的C 数组,例如NSString __unsafe_unretained *myStrings = { @"Foo", @"Bar", @"Baz", nil };
      • @shannoga - 不,您必须手动指定 __weak 作为限定符才能使用这些指针。您仍然可以将 __unsafe_unretained 与纯 5.0 目标一起使用,它的行为不会像 __weak。如果您想要根据您的目标是否支持在两种模式之间切换的东西,您可以使用我在这里建议的编译器特定定义:stackoverflow.com/a/8594878/19679
      • @jlehr - NSString *myStrings = { @"Foo", @"Bar" }; 不是有效的 Objective-C 语法; @"Foo" 本身具有 NSString* 类型。也许你的意思是NSString *myStrings[] = { @"Foo", @"Bar" };,但在那种情况下,我真的不明白__unsafe_unretained 会特别有用。
      • @Quuxplusone 在这两个方面都是正确的——我将 C 数组与结构混合在一起。我应该说的是__unsafe_unretained 可以是指向 NSString 常量的有用的 C 结构成员,例如struct foo { __unsafe_unretained NSString * const s; int x; };
      • Class也有影响。见:stackoverflow.com/a/14245894/392847
      【解决方案4】:

      关于 __unsafe_unretained 的另一个观察结果:我的设备上的应用程序崩溃了,而在 iVar 声明为 __unsafe_unretained 的模拟器上没有! 是的,这是 ARC 迁移代码中的一个错误,但这是我第一次注意到设备和模拟器之间存在这种差异。

      【讨论】:

        猜你喜欢
        • 2023-03-20
        • 2012-03-09
        • 1970-01-01
        • 2012-01-30
        • 2012-02-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多