你的位置:首页 > 操作系统

[操作系统]@property中的copy.strong.weak总结


1.NSString类型的属性为什么用copy

  NSString类型的属性可以用strong修饰,但会造成一些问题,请看下面代码

 

#import "ViewController.h"@interface ViewController ()@property(nonatomic,strong) NSString *nameStrong;@property(nonatomic,copy) NSString *nameCopy;@end@implementation ViewController- (void)viewDidLoad {  [super viewDidLoad];    NSMutableString *muStr = [NSMutableString stringWithString:@"zhangsan"];  self.nameCopy = muStr ;  self.nameStrong = muStr;  NSLog(@"可变字符串修改前nameStrong= %@ nameCopy=%@",self.nameStrong,self.nameCopy);  [muStr appendString:@"feng"];   NSLog(@"可变字符串修改后nameStrong= %@ nameCopy=%@",self.nameStrong,self.nameCopy);  }
打印结果如下:

2016-03-15 10:10:25.772 string[619:12684] 可变字符串修改前nameStrong= zhangsan nameCopy=zhangsan

2016-03-15 10:10:25.773 string[619:12684] 可变字符串修改后nameStrong= zhangsanfeng nameCopy=zhangsan

可变字符串改变时,strong修饰的字符串也跟着改变了,而copy修饰的字符串没有改变

 

  总结:用strong修饰的字符串,当NSMutableString的字符串给他赋值时,NSMutableString的字符串变了,它也会跟着改变,因为stong只是指针的引用,引用计数加1。

  用copy修饰的字符串,不会随着源头的改变而改变,因为copy会复制一份。

 如果源头的字符串是不可变的,那么用copy和strong是一样的,因为源头是不可变的字符串嘛,所以用copy还是strong看你的需要了,想让他随着源头改变就用strong,不想改变有用copy,一般不会让它改变,所以安全起见,字符串会用copy

 

2.代理.手动拖线的控件为什么用weak

  self->对象(比如person对象)->代理->self(设置代理时:self.delegate=self);

  会造成循环引用, 使用weak表明该属性定义了一种非拥有关系,为这种属性设置新值时,既不保留新值也不会释放旧值。

  首先手动拖线的控件用weak不是因为会造成循环引用,self->view->sunViews->控件,这样已经有个强引用了,如果控件用strong,self->控件,这个控件有两个强引用,释放时要剪断两个对他的引用,如果有一个没有释放,这个控件就不能释放了,当然用strong也没有错,还更加安全呢。

 

3.block为什么用copy

  block的方法内容是在栈区的,首先栈区是系统自动管理的,随时会清除内存,,再访问时可能会造成野指针,copy关键字会把block的内容复制到堆区,堆区由程序员自己管理。