ARC-不安全不保留的意思是什么?

我只是想确认一下我说对了:

  1. 我需要 __unsafe_unretain对象,我不拥有?
  2. 如果一个对象是 __unsafe_unretained我需要在 @property中使用 assign吗?这是否意味着对象不会被保留,而只是引用我分配给它的对象?
  3. 除了委托之外,我什么时候想要使用它?
  4. 这是 ARC 的东西还是之前用过的?
43060 次浏览
  1. 不,您也可以对不属于您的对象使用 weak
  2. 不,您也可以在属性上使用 unsafe_unretained
  3. 我的理解是,unsafe_unretained项目就像 weak一样,当它们指向的项目被释放(以及随之而来的开销)时,没有额外的清除它们的安全性。
  4. 这完全是异常点研究中心的事。

__unsafe_unretained与 ARC 之前对象的默认存储相同。对于 ARC,默认值现在是 __strong,这意味着在引用超出作用域之前,您有一个对它的引用。

LLVM Compiler 3.0引入了四个新的所有权限定符: __strong__autoreleasing__unsafe_unretained__weak。根据 说明书,前三个甚至在 ARC 之外也可以使用。

正如 Joshua 所指出的,默认情况下,所有指针都是 ARC 下的 __strong。这意味着当一个对象被分配给那个指针时,只要那个指针引用它,它就会被保留。这对于大多数事情来说都是好的,但是它为保留循环打开了可能性,正如我在我的答案 给你中所描述的。例如,如果一个对象包含另一个对象作为实例变量,但是第二个对象有一个强链接回到第一个对象作为其委托,那么这两个对象将永远不会被释放。

正是由于这个原因,才存在 __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和雪豹,你必须使用 __unsafe_unretained修饰符,或者使用类似 Mike Ash 的 MAZeroingWeakRef

另一个关于不安全不保留的观察: 我的应用程序在设备上崩溃了,模拟器上的 没有崩溃了,iVars 被声明为不安全不保留! 是的,这是 ARC 迁移代码中的一个 bug,但这是我第一次注意到设备和模拟器之间的差异。