Objective-C属性修饰符strong和copy的区别
2016-10-31 11:22
274 查看
copy和strong都可以用于NSString和NSArray 那么,什么时候用copy,什么时候用strong呢?
#记住一点,当你给你的的NSString或者NSArray对象赋值时,
1.如果来源是NSMutableString或NSMutableArray,为了防止数据发生变化,这种情况就必须要用copy;
2.如果你确定来源是不可变类型的,比如@"http://www.seventopalsy.com/"这种固定的字符串,那么用strong比较好下面我们来分析一下copy和strong的区别
首先,为什么要用copy?
因为copy安全!
copy修饰的NSString,在初始化时,如果来源是NSMutableString的话,会对来源进行一次深拷贝,将来源的内存地址复制一份,这样,两个对象就一点关系就没有了,无论你怎么操作来源,都不会对自己的NSString有任何影响 比如: 你有一个@property(nonatomic,copy) NSString *str; 然后有一个NSMutableString *sourceStr; 当你进行str = sourceStr操作之后,紧接着你又改变了sourceStr的内容sourceStr = @"change";那么str的内容并不会改变. 如果你的str不是copy修饰的,而是strong修饰的,那么str的值也会变成@"change";因为strong是浅拷贝的,并不会对来源的内存地址进行拷贝 那么问题来了,既然copy安全,那为什么不都用copy? 这里我们需要了解一点,copy修饰的NSString在进行set操作时,底层是这样实现的: 我们还是举上面那个例子,进行str = sourceStr操作时,内部会执行一个操作: str = [sourceStr copy]; 那么这个copy里面做了什么呢? if ([str isMemberOfClass:[str class]]) 没错,就是进行一次判断,判断来源是可变的还是不可变的,如果是不可变,那么好,接下来的操作就跟strong修饰的没有区别,进行浅拷贝;如果是可变的,那么会进行一次深拷贝 所以,copy操作内部会进行判断,你别小看了这个if操作所消耗的内存,一次不重要,十次可能也可以忽略不计,但当你的项目十分庞大时,有成百上千个个NSString对象,多多少少会对你的app的性能造成一定的影响.对源头是NSMutableString的字符串,strong仅仅是指针引用,增加了引用计数器,这样源头改变的时候,用strong声明的变量(无论被赋值的变量是可变的还是不可变的),它也会跟着改变;而copy声明的变量,它不会跟着源头改变,它实际上是深拷贝。对源头是NSString的字符串,无论是strong声明的变量还是copy声明的变量,当第二次源头的字符串重新指向其它的地方的时候,它还是指向原来的最初的那个位置,也就是说其实二者都是指针引用,也就是浅拷贝。另外说明一下,这两者对内存计数的影响都是一样的,都会增加内存引用计数,都需要在最后的时候做处理。其实说白了,对字符串为啥要用这两种方式?我觉得还是一个安全问题,比如声明的一个NSString *str变量,然后把一个NSMutableString *mStr变量的赋值给它了,如果要求str跟着mStr变化,那么就用retain;如果str不能跟着mStr一起变化,那就用copy。而对于要把NSString类型的字符串赋值给str,那两都没啥区别。不会影响安全性,内存管理也一样。
说到底,其实就是不同的修饰符,对应不同的setter方法,
1. strong对应的setter方法,是将_property先release(_property release),然后将参数retain(property retain),最后是_property = property。
2. copy对应的setter方法,是将_property先release(_property release),然后拷贝参数内容(property copy),创建一块新的内存地址,最后_property = property。
代码示例:
@interface Person : NSObject @property (strong, nonatomic) NSArray *strongArray; @property (copy, nonatomic) NSArray *copyArray; @end @implementation Person //省略setter方法 @end //Person调用 main(){ NSMutableArray *mutableBooks = [@[@"book1"] mutableCopy]; Person *person = [[Person alloc] init]; person.strongArray = mutableBooks; person.copyArray = mutableBooks; [mutableBooks addObject:@"book2"]; NSLog(@"strongArray:%@",person.strongArray); NSLog(@"copyArray:%@",person.copyArray); }
//输出结果:使用strong修饰的person.strongArray输出是[book1,book2],而使用copy修饰的person.copyArray输出是[book1]。
相关文章推荐
- Objective-C属性修饰符strong和copy的区别
- Objective-C属性修饰符strong和copy的区别
- 声明NSString属性用 Copy 与 strong 的区别
- [iOS]NSString到底使用Copy还是使用Strong属性,有什么区别
- iOS开发-------属性用copy、strong修饰的区别
- iOS开发-------属性用copy、strong修饰的区别
- 【整理】Object-C中的属性(Property)的Setter:assign,copy,retain,weak,strong之间的区别和联系
- objective-c的strong与copy的区别,深拷贝与浅拷贝的区别,copy与mutableCopy的区别
- iOS 属性修饰符Copy 还是Strong
- 数组的属性修饰符到底用strong还是copy?
- NSString类型copy和strong属性的区别
- iOS中 property中的属性strong 、weak、copy 、assign 、retain 、unsafe_unretained 与autoreleasing区别和作用详解
- 个人理解的IOS开发Objective-C中的属性readwrite,readonly,retain,assign,copy,nonatomic,strong,weak.
- ios-关于深拷贝和浅拷贝和属性中的copy和strong的区别
- Objective-C中类属性的 copy, tetain, assign , readonly , readwrite, nonatomic区别
- objective-c中property 的属性strong,weak, retain, copy
- 使用copy与strong声明NSString属性的区别
- property中的属性strong 、weak、copy 、assign 、retain 、unsafe_unretained 与autoreleasing区别和作用详解
- iOS 属性修饰符之NSString--copy--strong
- [iOS]NSString到底使用Copy还是使用Strong属性,有什么区别