ARC为属性引入了两个新的内存管理属性,强和弱。
除了复制,这显然是完全不同的东西,强与保留和弱与赋值之间有什么区别吗?
根据我的理解,这里唯一的区别是weak会将nil赋值给指针,而assign不会,这意味着当我向指针发送消息时,程序将崩溃,一旦它被释放。但如果我用weak,这就不会发生,因为message send给nil什么都不会做。
我不知道坚强和保留之间有什么区别。
是否有任何理由,为什么我应该使用分配和保留在新项目,或者是那种被弃用?
ARC为属性引入了两个新的内存管理属性,强和弱。
除了复制,这显然是完全不同的东西,强与保留和弱与赋值之间有什么区别吗?
根据我的理解,这里唯一的区别是weak会将nil赋值给指针,而assign不会,这意味着当我向指针发送消息时,程序将崩溃,一旦它被释放。但如果我用weak,这就不会发生,因为message send给nil什么都不会做。
我不知道坚强和保留之间有什么区别。
是否有任何理由,为什么我应该使用分配和保留在新项目,或者是那种被弃用?
当前回答
据我所知,坚强和保留是同义词,所以它们的作用完全相同。
弱函数类似于赋值,但在它指向的对象被释放后自动设为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.
}
这是一个非常特殊的例子,但是它告诉我们这些弱变量是如何工作的,以及什么时候它们是无效的。
其他回答
为了理解强引用和弱引用,考虑下面的例子: 假设我们有一个名为displayLocalVariable的方法。
-(void)displayLocalVariable
{
NSString myName = @"ABC";
NSLog(@"My name is = %@", myName);
}
在上述方法中,myName变量的作用域仅限于displayLocalVariable方法,一旦方法完成,myName变量将从内存中释放字符串“ABC”。
现在如果我们想在视图控制器生命周期中保持myName变量值。为此,我们可以创建名为username的属性,它将具有对变量myName的强引用(参见self。username = myName;在以下代码中),如下所示:
@interface LoginViewController ()
@property(nonatomic,strong) NSString* username;
@property(nonatomic,weak) NSString* dummyName;
- (void)displayLocalVariable;
@end
@implementation LoginViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(void)viewWillAppear:(BOOL)animated
{
[self displayLocalVariable];
}
- (void)displayLocalVariable
{
NSString myName = @"ABC";
NSLog(@"My name is = %@", myName);
self.username = myName;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
@end
现在在上面的代码中,你可以看到myName已被分配给self。用户名和自我。用户名对myName有强引用(正如我们在接口中使用@property声明的那样)(间接地,它对“ABC”字符串有强引用)。因此字符串myName直到self才会从内存中被释放。用户名已激活。
弱引用
现在考虑将myName赋值给弱引用dummyName self。dummyName = myName; 与强引用不同,弱引用将只保留myName,直到有对myName的强引用。 请参阅下面的代码以理解弱引用,
-(void)displayLocalVariable
{
NSString myName = @"ABC";
NSLog(@"My name is = %@", myName);
self.dummyName = myName;
}
在上面的代码中,有对myName的弱引用(即。自我。dummyName对myName有弱引用),但没有对myName的强引用,因此是self。dummyName将不能保存myName值。
现在再次考虑下面的代码,
-(void)displayLocalVariable
{
NSString myName = @"ABC";
NSLog(@"My name is = %@", myName);
self.username = myName;
self.dummyName = myName;
}
在以上代码中自我。username对myName有强引用,因此是self。即使在方法结束后,dummyName现在也会有一个myName值,因为myName有一个与之关联的强引用。
现在,每当我们对一个变量进行强引用时,它的保留计数就会增加1,并且该变量不会被释放,保留计数达到0。
希望这能有所帮助。
从过渡到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对象的弱引用。
据我所知,坚强和保留是同义词,所以它们的作用完全相同。
弱函数类似于赋值,但在它指向的对象被释放后自动设为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.
}
这是一个非常特殊的例子,但是它告诉我们这些弱变量是如何工作的,以及什么时候它们是无效的。
strong和retain的区别:
在iOS4中,强等于留住 它意味着你拥有该对象,并将其保存在堆中,直到不再指向它为止 如果你写retain,它会像strong一样自动工作
weak和assign的区别:
“弱”引用是指您不保留的引用,只要其他人强烈地指向它,您就会保留它 当对象被“释放”时,弱指针被自动设置为nil “assign”属性属性告诉编译器如何合成属性的setter实现
原子/原子
非原子的比原子的快得多 总是使用nonatomic,除非你对atomic有非常具体的要求,这应该是罕见的(atomic不能保证线程安全-只有当它同时被另一个线程设置时才会暂停访问属性)
强/弱/分配
使用strong来保留对象——尽管关键字retain是同义词,但最好使用strong代替 如果你只想要一个指向对象的指针而不保留它,请使用weak -这有助于避免保留周期(例如。delegate)——当对象被释放时,它会自动空出指针 对原语使用赋值-与weak完全相同,只是它在释放时不会清空对象(默认设置)
(可选)
copy
使用它创建对象的浅拷贝 始终将不可变属性设置为copy的好做法——因为可变版本可以传递到不可变属性中,copy将确保您始终处理不可变对象 如果传入一个不可变对象,它将保留它-如果传入一个可变对象,它将复制它
只读的
使用它来禁用属性的设置(如果存在违规,则防止代码编译) 您可以通过直接通过其实例变量更改变量或在getter方法本身中更改getter所传递的内容