Objective-C ARC:强大vs保留和弱与分配
ARC引入的属性有两个新的内存pipe理属性, weak
。
除了copy
,这显然是完全不同的东西, strong
与保与weak
assign
有区别?
根据我的理解,这里唯一的区别是weak
将指向nil
,而assign
不会,这意味着一旦释放指针,就会向指针发送消息时程序崩溃。 但如果我使用weak
,这将不会发生,因为消息发送到nil
将不会做任何事情。
我不知道strong
和retain
之间的任何差异。
为什么我应该使用assign
和retain
在新项目中,还是有什么理由被弃用?
从转换到ARC发行说明 (属性属性部分中的示例)。
// The following declaration is a synonym for: @property(retain) MyClass *myObject; @property(strong) MyClass *myObject;
如此strong
的财产声明中的retain
是一样的。
对于ARC项目,我将使用strong
而不是retain
,我将使用assign
for C原始属性,而对于Objective-C对象的弱引用则使用weak。
阅读了这么多文章后,Stackoverflow发布和演示应用程序来检查variables属性的属性,我决定把所有的属性信息放在一起:
- primefaces//默认
- 非primefaces
- 强=保留/ /默认
- 弱
- 保留
- 分配//默认
- unsafe_unretained
- 复制
- 只读
- 读写//默认
下面是详细的文章链接,你可以find上面提到的所有属性,这一定会帮助你。 非常感谢所有在这里给出最佳答案的人!
iOS中的variables属性或修饰符
1.strong(iOS4 =保留)
- 它说:“把它留在堆里,直到我不再指向它”
- 换句话说,“我是业主,你不能像保留那样瞄准罚款”
- 只有在需要保留对象的情况下才能使用强壮。
- 默认情况下,所有的实例variables和局部variables都是强指针。
- 我们通常使用强大的UIViewControllers(UI项目的父母)
- 强与ARC使用,它基本上可以帮助你,不必担心一个对象的保留计数。 ARC完成后会自动为您发布。使用关键字strong意味着您拥有该对象。
例:
@property (strong, nonatomic) ViewController *viewController; @synthesize viewController;
2.弱点 –
- 它说“只要别人强烈地指出,
- 与分配,保留或释放一样的事情
- 一个“弱”的参考是你不保留的参考。
- 我们通常对IBOutlets(UIViewController的Childs)使用weak。这是可行的,因为子对象只要父对象有效就只需要存在。
- 弱引用是一个引用,它不保护引用的对象不被垃圾收集器收集。
- 弱是本质上的分配,一个没有保留的财产。 除了释放对象的时候,弱指针自动设置为零
例如:
@property (weak, nonatomic) IBOutlet UIButton *myButton; @synthesize myButton;
强和弱的解释, 感谢BJ荷马 :
想象一下,我们的目标是一只狗,而狗想逃跑(被释放)。
强壮的指针就像狗狗上的皮带。 只要你有狗的皮带,狗不会逃跑。 如果五个人把他们的皮带绑在一只狗身上(五个指向一个物体的强指针),那么在所有五个皮带脱离之前,狗不会跑掉。
另一方面,弱指针就像小孩子指着狗说:“看!一条狗!” 只要狗仍然在拴住,小孩子仍然可以看到狗,他们仍然指向它。 然而,只要所有的皮带都分离了,不pipe有多less小孩指着它,狗都会跑掉。
只要最后一个强指针(皮带)不再指向一个对象,对象将被释放,所有弱指针将被清零。
当我们使用弱?
如果你想避免保留周期(例如,父母保留孩子,孩子保留父母,所以永远不会被释放)。
3.retain = strong
- 它被保留,旧的值被释放,并被分配保留指定应发送新的值
- 保留任务,并发送旧的价值 – 释放
- 保持一样强壮。
- 苹果说,如果你写保留它会自动转换/工作像只有强。
- 像“alloc”这样的方法包含一个隐含的“保留”
例:
@property (nonatomic, retain) NSString *name; @synthesize name;
4.assign
- assign是默认值,只是执行variables赋值
- assign是一个属性属性,告诉编译器如何综合属性的setter实现
- 我将使用C语言的原始属性赋值,弱赋值给Objective-C对象。
例:
@property (nonatomic, assign) NSString *address; @synthesize address;
据我所知, strong
和retain
是同义词,所以他们完全一样。
那么weak
几乎就像assign
,但是在对象之后自动设置为零,它指向的是被释放的。
这意味着,你可以简单地replace它们。
但是 ,我遇到了一个特例,我不得不使用assign
,而不是weak
。 假设我们有两个属性delegateAssign
和delegateWeak
。 在这两个存储我们的代表,这是拥有我们的唯一有力的参考。 委托正在释放,所以我们的-dealloc
方法也被调用。
// Our delegate is deallocating and there is no other strong ref. - (void)dealloc { [delegateWeak doSomething]; [delegateAssign doSomething]; }
代表已经处于释放过程,但仍未完全释放。 问题是, 对他的weak
引用已经无效了! 属性delegateWeak
包含nil,但是delegateAssign
包含有效的对象(所有属性已经被释放并且是无效的,但仍然有效)。
// Our delegate is deallocating and there is no other strong ref. - (void)dealloc { [delegateWeak doSomething]; // Does nothing, already nil. [delegateAssign doSomething]; // Successful call. }
这是一个非常特殊的情况,但它揭示了这些weak
variables是如何工作的,什么时候它们被废除了。
非primefaces/primefaces
- 非primefaces比primefaces快得多
- 总是使用非primefaces,除非你有一个非常具体的要求primefaces,这应该是罕见的(primefaces不保证线程安全 – 只有失去访问属性,当它同时被另一个线程设置)
强/弱/分配
- 使用强保留对象 – 虽然关键字保留是同义词,但最好使用强代替
- 如果只需要一个指向对象的指针而不保留它,则使用较弱 – 对于避免保留周期(即委托)有用 – 当对象被释放时它将自动清零指针
- 使用分配为主 – 完全一样弱,除了不释放对象时释放(默认设置)
(可选的)
复制
- 用它来创build对象的浅拷贝
- 好的做法总是设置不可变的属性进行复制 – 因为可变的版本可以传递到不可变的属性中,复制将确保你总是处理一个不可变的对象
- 如果一个不可变对象被传入,它将保留它 – 如果一个可变对象被传入,它将复制它
只读
- 使用它来禁用该属性的设置(防止代码编译如果有违规)
- 您可以通过直接通过实例variables更改variables,或者通过getter方法本身来更改getter提供的内容
Clang关于Objective-C自动引用计数(ARC)的文档清楚地解释了所有权限定符和修饰符:
有四个所有权限定符:
- __ 自动释放
- __ 强
- __ * unsafe_unretained *
- __ 弱
如果一个types具有__ autoreleasing ,__ strong或__ weak的限定条件,则该types是不受限制的。
然后有六个声明属性的所有权修饰符:
- 分配意味着__ * unsafe_unretained *所有权。
- 副本意味着__ 强大的所有权,以及setter上复制语义的通常行为。
- 保留意味着强大的所有权。
- 强有力的意味着强大的所有权。
- * unsafe_unretained *意味着__ * unsafe_unretained *所有权。
- 弱意味着所有权较弱 。
除了弱点以外 ,这些修改器可以在非ARC模式下使用。
在语义上,所有权限定词在五个托pipe操作中有不同的含义:阅读,分配,初始化,销毁和移动,其中大部分时间我们只关心分配操作的差异。
在评估赋值运算符时发生赋值。 语义根据资格而有所不同:
- 对于强壮的物体,首先保留新的指针, 其次,左值加载了原始语义; 第三,新的pointee用原始语义存储在左值中; 最后,旧的指针被释放。 这不是自动执行的; 面对并发的加载和存储,必须使用外部同步来保证安全。
- 对于__ 弱对象,左值更新为指向新的指针,除非新指针是当前正在进行释放的对象,在这种情况下,左值被更新为空指针。 这必须primefaces地执行对其他对象的任务,从对象读取,并最终释放新的指针。
- 对于__ * unsafe_unretained *对象,新的pointee使用原语语义存储到左值。
- 对于__ 自动释放对象,新指针被保留,自动释放,并使用原语语义存储到左值中。
阅读,初始化,销毁和移动的另一个区别请参阅文档中的第4.2节语义 。
强大:
- 属性不会销毁,但只有当你设置属性为零,对象才会被销毁
- 默认情况下,所有的实例variables和局部variables都是强指针。
- 只有在需要保留对象的情况下才能使用强壮。
- 我们通常使用强大的UIViewControllers(UI项目的父母)
- IOS 4(非ARC)我们可以使用保留关键字
- IOS 5(ARC)我们可以使用强关键字
例如:@property(strong,nonatomic)ViewController * viewController;
@synthesize viewController;
弱
按默认自动获取并设置为零
- 我们通常使用弱IBOutlets(UIViewController的孩子)和委托
- 与分配,保留或释放一样的事情
例如:@property(弱,非primefaces)IBOutlet UIButton * myButton;
@synthesize myButton;
强与保留的区别:
- 在iOS4中,strong等于保留
- 这意味着你拥有这个对象并把它保存在堆中,直到不再指向它
- 如果你写保留,它会自动工作,就像强
弱者与分配的区别:
- 一个“弱”的引用是你不保留的一个引用,只要别人强烈地指向它,你就保留它
- 当对象被“解除分配”时,弱指针被自动设置为零
- “assign”属性属性告诉编译器如何综合属性的setter实现