ARC, strong
和 weak
引入的属性有两个新的内存管理属性 .
除了 copy
,这显然是完全不同的东西, are there any differences between strong vs retain and weak vs assign?
根据我的理解,这里唯一的区别是 weak
将指定 nil
指针,而 assign
赢得't, which means the program will crash when I send a message to the pointer once it'已被释放 . 但是,如果我使用 weak
,这将不会发生,因为发送到 nil
的消息将不会执行任何操作 .
我不知道 strong
和 retain
之间的任何差异 .
Is there any reason why should I use assign and retain in new projects, or are the kind of being deprecated?
8 回答
来自Transitioning to ARC Release Notes(属性属性部分中的示例) .
所以
strong
与属性声明中的retain
相同 .对于ARC项目,我会使用
strong
而不是retain
,我会使用assign
作为C基本属性,使用weak
作为对Objective-C对象的弱引用 .强者和保留者之间的区别:
在iOS4中,strong等于保留
这意味着您拥有该对象并将其保留在堆中,直到不再指向它为止
如果你写保留它将自动工作就像强
弱与分配之间的差异:
“弱”参考是您不保留的参考,只要其他人强烈指向它,您就会保留它
当对象被“解除分配”时,弱指针自动设置为nil
"assign"属性属性告诉编译器如何合成属性的setter实现
在阅读了如此多的文章Stackoverflow帖子和演示应用程序来检查变量属性属性后,我决定将所有属性信息放在一起:
atomic //默认
非原子的
strong =保留//默认
弱
保留
assign //默认
unsafe_unretained
副本
只读
readwrite //默认
下面是详细的文章链接,您可以在其中找到上面提到的所有属性,这肯定会对您有所帮助 . 非常感谢所有在这里给出最佳答案的人!
1.strong (iOS4 = retain )
它说"keep this in the heap until I don't point to it anymore"
换句话说" I'am the owner, you cannot dealloc this before aim fine with that same as retain"
仅在需要保留对象时才使用strong .
默认情况下,所有实例变量和局部变量都是强指针 .
我们通常对UIViewControllers使用strong(UI项目的父项)
strong与ARC一起使用,它基本上可以帮助您,而不必担心对象的保留计数 . 完成后,ARC会自动为您释放它 . 使用关键字strong表示您拥有该对象 .
例:
2.weak -
它说"keep this as long as someone else points to it strongly"
与分配相同,不保留或释放
"weak"参考是您未保留的参考 .
我们通常对IBOutlets使用弱(UIViewController的Childs) . 这是有效的,因为只要父对象存在,子对象才需要存在 .
弱引用是一种引用,它不保护引用的对象不被垃圾收集器收集 .
弱基本上是分配,一个没有保留的属性 . 除了释放对象时,弱指针自动设置为nil
示例:
Strong & Weak Explanation, Thanks to BJ Homer:
当我们使用弱者?
你想要使用弱的唯一一次是,如果你想避免保留周期(例如父母保留孩子而孩子保留父母,所以两者都没有被释放) .
3.retain = strong
保留,旧值被释放并且被分配保留指定应该发送新值
保留赋值,旧值发送-release
retain与strong相同 .
apple说如果你写保留它会自动转换/工作就像强大一样 .
像"alloc"这样的
方法包含一个隐含的"retain"
例:
4.assign
assign是默认值,只是执行变量赋值
assign是一个属性属性,它告诉编译器如何合成属性的setter实现
我将对C原始属性使用assign,对于对Objective-C对象的弱引用使用weak .
例:
Clang在Objective-C Automatic Reference Counting (ARC)上的文件清楚地解释了所有权限定符和修饰符:
然后,声明属性有六个所有权修饰符:
语义学上,所有权限定符在_414038中具有不同的含义:阅读,分配,初始化,销毁和移动,其中大多数时候我们只关心分配操作的差异 .
阅读,初始化,毁灭和移动的另一个区别,请参阅Section 4.2 Semantics in the document .
非原子/原子
非原子比原子快得多
总是使用非原子,除非你有一个非常特殊的原子要求,这应该是罕见的(原子不同时由另一个线程设置)
强/弱/分配
使用strong来保留对象 - 虽然关键字retain是同义词,但最好使用strong
如果你只想要一个指向对象的指针而不保留它,则使用weak - 对于避免保留周期(即委托)很有用 - 当对象被释放时它会自动将指针弄为零
使用赋值为primatives - 完全像weak一样,除了它在释放时不会丢弃对象(默认设置)
(可选)
副本
用它来创建对象的浅表副本
总是将不可变属性设置为复制的良好实践 - 因为可变的版本可以传递给不可变属性,复制将确保您将始终处理不可变对象
如果传入一个不可变对象,它将保留它 - 如果传入一个可变对象,它将复制它
只读
使用它来禁用属性的设置(如果存在违规则阻止代码编译)
您可以通过直接通过其实例变量更改变量,或者在getter方法本身内更改getter传递的内容
强:
属性不会销毁,但只有将属性设置为nil才会销毁对象
默认情况下,所有实例变量和局部变量都是强指针 .
仅在需要保留对象时才使用strong .
我们通常对UIViewControllers使用strong(UI项目的父项)
IOS 4(非ARC)我们可以使用保留KeyWord
IOS 5(ARC)我们可以使用强关键字
示例:@property(强,非原子)ViewController * viewController;
@synthesize viewController;
弱
默认情况下自动获取并设置为nil
我们通常对IBOutlets(UIViewController的Childs)和委托使用weak
与分配相同,不保留或释放
示例:@property(弱,非原子)IBOutlet UIButton * myButton;
@synthesize myButton;
据我所知,
strong
和retain
是同义词,所以它们完全相同 .然后
weak
几乎就像assign
,但是在指向的对象之后自动设置为nil,被释放 .That means, you can simply replace them.
However ,我遇到过一个特殊情况,我必须使用
assign
,而不是weak
. 假设我们有两个属性delegateAssign
和delegateWeak
. 两者都存储了我们的代表,即拥有唯一强大的参考资料 . 代表正在解除分配,所以我们的-dealloc
方法也被调用 .委托已经处于释放过程中,但仍未完全取消分配 . 问题是 weak references to him are already nullified! 属性
delegateWeak
包含nil,但delegateAssign
包含有效对象(所有属性已经释放并且无效,但仍然有效) .这是一个非常特殊的情况,但它揭示了这些
weak
变量如何工作以及它们何时无效 .为了理解Strong和Weak引用,请考虑下面的示例,假设我们有一个名为displayLocalVariable的方法 .
在上面的方法中,myName变量的范围仅限于displayLocalVariable方法,一旦方法完成,保存字符串“ABC”的myName变量将从内存中释放出来 .
现在,如果我们想在整个视图控制器生命周期中保存myName变量值,该怎么办呢?为此,我们可以创建名为username的属性,该属性将具有对myName变量的强引用(参见下面的代码中的
self.username = myName;
),如下所示,现在在上面的代码中你可以看到myName已经被分配给self.username而self.username有一个强引用(我们在接口中使用@property声明)到myName(间接它有强引用“ABC”字符串) . 因此,在my.username处于活动状态之前,String myName不会从内存中释放 .
现在考虑将myName分配给dummyName,这是一个弱引用,self.dummyName = myName;与强引用不同,Weak只保留myName,直到有对myName的强引用 . 请参阅下面的代码以了解弱参考,
在上面的代码中有对myName的弱引用(即self.dummyName具有对myName的弱引用),但是没有对myName的强引用,因此self.dummyName将无法保存myName值 .
现在再考虑下面的代码,
在上面的代码中,self.username具有对myName的强引用,因此即使在方法结束之后,self.dummyName现在也将具有myName值,因为myName具有与之关联的Strong引用 .
现在每当我们对变量进行强引用时,它的保留计数增加1,变量将不会被释放,保留计数达到0 .
希望这可以帮助 .