Objective-C ARC:强大vs保留和弱与分配

ARC引入的属性有两个新的内存pipe理属性, weak

除了copy ,这显然是完全不同的东西, strong与保与weak assign有区别?

根据我的理解,这里唯一的区别是weak将指向nil ,而assign不会,这意味着一旦释放指针,就会向指针发送消息时程序崩溃。 但如果我使用weak ,这将不会发生,因为消息发送到nil将不会做任何事情。

我不知道strongretain之间的任何差异。

为什么我应该使用assignretain在新项目中,还是有什么理由被弃用?

从转换到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属性的属性,我决定把所有的属性信息放在一起:

  1. primefaces//默认
  2. 非primefaces
  3. 强=保留/ /默认
  4. 保留
  5. 分配//默认
  6. unsafe_unretained
  7. 复制
  8. 只读
  9. 读写//默认

下面是详细的文章链接,你可以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; 

据我所知, strongretain是同义词,所以他们完全一样。

那么weak几乎就像assign ,但是在对象之后自动设置为零,它指向的是被释放的。

这意味着,你可以简单地replace它们。

但是 ,我遇到了一个特例,我不得不使用assign ,而不是weak 。 假设我们有两个属性delegateAssigndelegateWeak 。 在这两个存储我们的代表,这是拥有我们的唯一有力的参考。 委托正在释放,所以我们的-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. } 

这是一个非常特殊的情况,但它揭示了这些weakvariables是如何工作的,什么时候它们被废除了。

非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实现