我只是想确认一下我说对了:
__unsafe_unretain
__unsafe_unretained
@property
assign
weak
unsafe_unretained
__unsafe_unretained与 ARC 之前对象的默认存储相同。对于 ARC,默认值现在是 __strong,这意味着在引用超出作用域之前,您有一个对它的引用。
__strong
LLVM Compiler 3.0引入了四个新的所有权限定符: __strong、 __autoreleasing、 __unsafe_unretained和 __weak。根据 说明书,前三个甚至在 ARC 之外也可以使用。
__autoreleasing
__weak
正如 Joshua 所指出的,默认情况下,所有指针都是 ARC 下的 __strong。这意味着当一个对象被分配给那个指针时,只要那个指针引用它,它就会被保留。这对于大多数事情来说都是好的,但是它为保留循环打开了可能性,正如我在我的答案 给你中所描述的。例如,如果一个对象包含另一个对象作为实例变量,但是第二个对象有一个强链接回到第一个对象作为其委托,那么这两个对象将永远不会被释放。
正是由于这个原因,才存在 __unsafe_unretained和 __weak限定符。它们最常见的用途是用于委托,您可以用 weak或 unsafe_unretained属性为该委托定义一个属性(assign实际上是 unsafe_unretained) ,然后通过用 __weak或 __unsafe_unretained标记相应的实例变量来匹配该属性。这意味着委托实例变量仍将指向第一个对象,但不会导致该对象被保留,从而打破保留周期,并允许两个对象都被释放。
除了委托之外,这对于打破代码中可能形成的任何其他保留周期都很有用。有用的是,Leaks 工具现在包含一个 Cycles 视图,它以图形方式显示它在应用程序中发现的保留周期。
__unsafe_unretained和 __weak都可以防止对象的保留,但是方式略有不同。对于 __weak,指向对象的指针将在它所指向的对象的释放时转换为 nil,这是非常安全的行为。顾名思义,__unsafe_unretained将继续指向对象所在的内存,即使在释放对象之后也是如此。这可能导致由于访问释放的对象而导致的崩溃。
nil
那你为什么要用 __unsafe_unretained呢?不幸的是,__weak只支持 iOS 5.0和 Lion 作为部署目标。如果你想回到 iOS 4.0和雪豹,你必须使用 __unsafe_unretained修饰符,或者使用类似 Mike Ash 的 MAZeroingWeakRef。
另一个关于不安全不保留的观察: 我的应用程序在设备上崩溃了,模拟器上的 没有崩溃了,iVars 被声明为不安全不保留! 是的,这是 ARC 迁移代码中的一个 bug,但这是我第一次注意到设备和模拟器之间的差异。