ARC为属性引入了两个新的内存管理属性,强和弱。

除了复制,这显然是完全不同的东西,强与保留和弱与赋值之间有什么区别吗?

根据我的理解,这里唯一的区别是weak会将nil赋值给指针,而assign不会,这意味着当我向指针发送消息时,程序将崩溃,一旦它被释放。但如果我用weak,这就不会发生,因为message send给nil什么都不会做。

我不知道坚强和保留之间有什么区别。

是否有任何理由,为什么我应该使用分配和保留在新项目,或者是那种被弃用?


当前回答

原子/原子

非原子的比原子的快得多 总是使用nonatomic,除非你对atomic有非常具体的要求,这应该是罕见的(atomic不能保证线程安全-只有当它同时被另一个线程设置时才会暂停访问属性)

强/弱/分配

使用strong来保留对象——尽管关键字retain是同义词,但最好使用strong代替 如果你只想要一个指向对象的指针而不保留它,请使用weak -这有助于避免保留周期(例如。delegate)——当对象被释放时,它会自动空出指针 对原语使用赋值-与weak完全相同,只是它在释放时不会清空对象(默认设置)

(可选)

copy

使用它创建对象的浅拷贝 始终将不可变属性设置为copy的好做法——因为可变版本可以传递到不可变属性中,copy将确保您始终处理不可变对象 如果传入一个不可变对象,它将保留它-如果传入一个可变对象,它将复制它

只读的

使用它来禁用属性的设置(如果存在违规,则防止代码编译) 您可以通过直接通过其实例变量更改变量或在getter方法本身中更改getter所传递的内容

其他回答

strong和retain的区别:

在iOS4中,强等于留住 它意味着你拥有该对象,并将其保存在堆中,直到不再指向它为止 如果你写retain,它会像strong一样自动工作


weak和assign的区别:

“弱”引用是指您不保留的引用,只要其他人强烈地指向它,您就会保留它 当对象被“释放”时,弱指针被自动设置为nil “assign”属性属性告诉编译器如何合成属性的setter实现

Clang关于Objective-C自动引用计数(ARC)的文档清楚地解释了所有权限定符和修饰符:

有四个所有权限定符: __autoreleasing 强烈 __ * unsafe_unretained * __weak 如果类型是限定的,则它具有重要的所有权限定 __autoreleased, __strong, or __weak。

声明的属性有六个所有权修饰符:

Assign表示__*unsafe_unretained*所有权。 Copy意味着__strong所有权,以及复制语义在setter上的通常行为。 Retain表示强烈的所有权。 Strong意味着__strong所有权。 *unsafe_unretained*表示__*unsafe_unretained*所有权。 Weak意味着__weak所有权。 除了weak,这些修饰符在非arc模式下可用。

从语义上讲,所有权限定符在读取、赋值、初始化、销毁和移动这五种托管操作中具有不同的含义,其中大多数情况下我们只关心赋值操作的差异。

Assignment occurs when evaluating an assignment operator. The semantics vary based on the qualification: For __strong objects, the new pointee is first retained; second, the lvalue is loaded with primitive semantics; third, the new pointee is stored into the lvalue with primitive semantics; and finally, the old pointee is released. This is not performed atomically; external synchronization must be used to make this safe in the face of concurrent loads and stores. For __weak objects, the lvalue is updated to point to the new pointee, unless the new pointee is an object currently undergoing deallocation, in which case the lvalue is updated to a null pointer. This must execute atomically with respect to other assignments to the object, to reads from the object, and to the final release of the new pointee. For __*unsafe_unretained* objects, the new pointee is stored into the lvalue using primitive semantics. For __autoreleasing objects, the new pointee is retained, autoreleased, and stored into the lvalue using primitive semantics.

read、Init、destroy、Moving的其他区别,请参见文档中4.2语义部分。

从过渡到ARC发布说明(在属性属性部分的例子)。

// The following declaration is a synonym for: @property(retain) MyClass *myObject;

@property(strong) MyClass *myObject;

所以strong和属性声明中的retain是一样的。

对于ARC项目,我会使用strong而不是retain,我会使用赋值来表示C原语属性,使用weak来表示对Objective-C对象的弱引用。

原子/原子

非原子的比原子的快得多 总是使用nonatomic,除非你对atomic有非常具体的要求,这应该是罕见的(atomic不能保证线程安全-只有当它同时被另一个线程设置时才会暂停访问属性)

强/弱/分配

使用strong来保留对象——尽管关键字retain是同义词,但最好使用strong代替 如果你只想要一个指向对象的指针而不保留它,请使用weak -这有助于避免保留周期(例如。delegate)——当对象被释放时,它会自动空出指针 对原语使用赋值-与weak完全相同,只是它在释放时不会清空对象(默认设置)

(可选)

copy

使用它创建对象的浅拷贝 始终将不可变属性设置为copy的好做法——因为可变版本可以传递到不可变属性中,copy将确保您始终处理不可变对象 如果传入一个不可变对象,它将保留它-如果传入一个可变对象,它将复制它

只读的

使用它来禁用属性的设置(如果存在违规,则防止代码编译) 您可以通过直接通过其实例变量更改变量或在getter方法本身中更改getter所传递的内容

据我所知,坚强和保留是同义词,所以它们的作用完全相同。

弱函数类似于赋值,但在它指向的对象被释放后自动设为nil。

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

但是,我遇到了一个特殊的情况,我必须使用assign,而不是weak。我们有两个属性,delegateAssign和delegateWeak。在这两个中都存储了我们的委托,它通过拥有唯一的强引用来拥有我们。委托正在释放,所以我们的-dealloc方法也被调用。

// Our delegate is deallocating and there is no other strong ref.
- (void)dealloc {
    [delegateWeak doSomething];
    [delegateAssign doSomething];
}

委托已处于释放过程中,但仍未完全释放。问题是对他的弱引用已经被无效了!属性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.
}

这是一个非常特殊的例子,但是它告诉我们这些弱变量是如何工作的,以及什么时候它们是无效的。