ios ARC - __unsafe_unretained 的含义?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8592289/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ARC - The meaning of __unsafe_unretained?
提问by shannoga
Just want to make sure that I got it right:
只是想确保我做对了:
- Do I need to
__unsafe_unretain
objects that I don't own? - If an object is
__unsafe_unretained
Do I need to useassign
in the@property
? Does that mean that the object is not retained, and just refers to the object I assign to? - When would I want to use it except of delegates?
- Is that an ARC thing or was it in use before?
- 我需要
__unsafe_unretain
我不拥有的对象吗? - 如果一个对象是
__unsafe_unretained
我需要assign
在@property
? 这是否意味着该对象没有保留,而只是指我分配给的对象? - 除了代表,我什么时候想使用它?
- 那是 ARC 的东西还是以前使用过?
回答by Brad Larson
The LLVM Compiler 3.0 introduces four new ownership qualifiers: __strong
, __autoreleasing
, __unsafe_unretained
, and __weak
. The first three are available even outside ARC, as per the specification.
该LLVM编译器3.0中引入了四个新的所有权预选赛:__strong
,__autoreleasing
,__unsafe_unretained
,和__weak
。根据规范,前三个甚至在 ARC 之外也可用。
As Joshua indicates, by default all pointers are implied to be __strong
under ARC. This means that when an object is assigned to that pointer, it is retained for as long as that pointer refers to it. This is fine for most things, but it opens up the possibility for retain cycles, as I describe in my answer here. For example, if you have an object that contains another object as an instance variable, but that second object has a strong link back to the first one as its delegate, the two objects will never be released.
正如 Joshua 指出的那样,默认情况下所有指针都暗示__strong
在 ARC 下。这意味着当一个对象被分配给该指针时,只要该指针指向它,它就会被保留。这对大多数事情都没有问题,但它为保留周期开辟了可能性,正如我在此处的回答中所描述的那样。例如,如果您有一个对象,其中包含另一个对象作为实例变量,但第二个对象与作为其委托的第一个对象有很强的链接,则这两个对象将永远不会被释放。
It is for this reason that the __unsafe_unretained
and __weak
qualifiers exist. Their most common use is for delegates, where you'd define a property for that delegate with the weak
or unsafe_unretained
attribute (assign
is effectively unsafe_unretained
), and then match that by marking the respective instance variable with __weak
or __unsafe_unretained
. This means that the delegate instance variable will still point back at the first object, but it will not cause that object to be retained, thus breaking the retain cycle and allowing both objects to be released.
正是因为这个原因,the__unsafe_unretained
和__weak
限定词才存在。它们最常见的用途是用于委托,您可以使用weak
orunsafe_unretained
属性(assign
有效地unsafe_unretained
)为该委托定义一个属性,然后通过用__weak
或标记相应的实例变量来匹配它__unsafe_unretained
。这意味着委托实例变量仍将指向第一个对象,但不会导致该对象被保留,从而打破保留循环并允许释放两个对象。
Beyond delegates, this is useful to break any other retain cycles that might form in your code. Helpfully, the Leaks instrument now includes a Cycles view, which shows retain cycles it discovers in your application in a graphical manner.
除了委托之外,这对于打破可能在您的代码中形成的任何其他保留循环非常有用。有用的是,Leaks 工具现在包括一个 Cycles 视图,它以图形方式显示它在您的应用程序中发现的保留周期。
Both __unsafe_unretained
and __weak
prevent the retention of objects, but in slightly different ways. For __weak
, the pointer to an object will convert to nil
on the deallocation of the object it points to, which is very safe behavior. As its name implies, __unsafe_unretained
will continue pointing to the memory where an object was, even after it was deallocated. This can lead to crashes due to accessing that deallocated object.
无论__unsafe_unretained
和__weak
防止物体的保留,但稍有不同的方式。对于__weak
,指向对象的指针将在其指向的对象nil
释放时转换为 ,这是非常安全的行为。顾名思义,__unsafe_unretained
将继续指向对象所在的内存,即使在它被释放后也是如此。由于访问该释放的对象,这可能导致崩溃。
Why would you ever use __unsafe_unretained
then? Unfortunately, __weak
is only supported for iOS 5.0 and Lion as deployment targets. If you want to target back to iOS 4.0 and Snow Leopard, you have to use the __unsafe_unretained
qualifier, or use something like Mike Ash's MAZeroingWeakRef.
那你为什么要使用__unsafe_unretained
?不幸的是,__weak
仅支持 iOS 5.0 和 Lion 作为部署目标。如果你想回到 iOS 4.0 和 Snow Leopard,你必须使用__unsafe_unretained
限定符,或者使用像 Mike Ash 的MAZeroingWeakRef 之类的东西。
回答by dasblinkenlight
- No, you could also use
weak
for objects that you do not own. - No, you could also use
unsafe_unretained
on the property. - My understanding is that
unsafe_unretained
items are just likeweak
, without the additional safety of clearing them out when the item they point to gets released (and the overhead that goes with it). - This is entirely an ARC thing.
- 不,您也可以
weak
用于您不拥有的对象。 - 不,您也可以
unsafe_unretained
在物业上使用。 - 我的理解是,
unsafe_unretained
项目就像weak
,当它们指向的项目被释放(以及随之而来的开销)时,没有额外的安全清除它们。 - 这完全是 ARC 的事情。
回答by Joshua Weinberg
__unsafe_unretained
is identical to what the default storage of an object was prior to ARC. With ARC the default is now __strong
meaning you have a reference to it until your reference goes out of scope.
__unsafe_unretained
与 ARC 之前对象的默认存储相同。使用 ARC,默认值现在__strong
意味着您可以引用它,直到您的引用超出范围。
回答by Gerd
Another observation on __unsafe_unretained: I've got crashes in my app on the device and NOTon simulator with iVars declared as __unsafe_unretained! Yes, it was a bug in the code from ARC migration, but it was the first time I noticed such a difference between device and simulator.
关于 __unsafe_unretained 的另一个观察结果:我在设备上的应用程序崩溃,而不是在模拟器上崩溃,iVars 声明为 __unsafe_unretained!是的,这是 ARC 迁移代码中的一个错误,但这是我第一次注意到设备和模拟器之间的这种差异。