retain assign copy在@propeerty中的使用实际上是通过控制set方法进行内存管理。
下面详细介绍:
1.retain:
例如:
@class Dog
@property(nonatomic,retain) Dog *dog;
注:nonatomic与atomic相对应,涉及线程,比较麻烦,这里不做赘述,读者仅需记住,nonatomic相对于atomic来说性能高,而声明属性时一般默认为atomic,故需在此申明nonatomic,这里使用了retain,那么在set方法中,究竟如何体现的呢?
- (void)setDog:(Dog *)dog
{
if(_dog != dog){ //判断是否需要重新赋值
[_dog release]; //释放旧引用,计数器-1
_dog = [dog retain]; //重新赋值,计数器+1
}
}
2.assign:
例如:
@property(nonatomic,assign)int count;
这里使用了assign,那么在set方法中,究竟如何体现的呢?
- (void)setCount:(int)count
{
_count = count;
}
3.copy
例如:
@property(nonatomic,copy)NSString * str;
这里使用了copy,那么在set方法中,究竟如何体现的呢?
- (void)setStr:(NSString *)str
{
if(_str != str){ //判断是否需要重新赋值
[_str release]; //释放旧引用,计数器-1
_str = [str copy]; //重新赋值,使用copy
}
}
总结:
1.retain:先release旧值,再retain新值,在上例中_dog与dog最终指向同一快内存区域。
2.assign:直接赋值,不考虑内存管理。
3.copy:先release旧值,再copy新值,copy的本质为复制该内存所存储的内容,重新创建一个对象赋给其相同的内容,很明显,在copy这个过程中也发生了一次retain,不过这是个全新的对象。在上例中,_str与str最终指向了不同的内存区域,但其内容一样。
property 中的strong 与weak
4.strong关键字与retain关似,用了它,引用计数自动+1,用实例更能说明一切
例如:
<span style="font-size:12px;">@property (nonatomic, strong) NSString*string1;
@property (nonatomic, strong) NSString*string2;
self.string1 = @"String 1";
self.string2 = self.string1;
self.string1 = nil;
NSLog(@"String 2 = %@",self.string2); </span>
结果是:
<span style="font-size:12px;">String 2 = String 1</span>
分析:
由于string2是strong定义的属性,所以引用计数+1,使得它们所指向的值都是@"String 1", 如果你对retain熟悉的话,这理解并不难。
5.weak关键字:
@property (nonatomic, strong) NSString*string1;
@property (nonatomic, weak) NSString*string2;
self.string1 = @"String 1";
self.string2 = self.string1;
self.string1 = nil;
NSLog(@"String 2 = %@",self.string2);
结果是:
String 2 = null
分析一下
由于self.string1与self.string2指向同一地址,且string2没有retain内存地址,而self.string1=nil释放了内存,所以string1为nil。
声明为weak的指针,指针指向的地址一旦被释放,这些指针都将被赋值为nil。这样的好处能有效的防止野指针。在c/c++开发过程中,为何大牛都说指针的空间释放了后,都要将指针赋为NULL. 在这儿用weak关键字帮我们做了这一步。