[关闭]
@whiteiOS 2017-03-27T08:45:21.000000Z 字数 3197 阅读 622

浅谈iOS中的copy

iOS学习之路


(一)概述

(二)浅拷贝和深拷贝

(三)系统对象的copy和mutableCopy

copy得到的总是不可变对象,不管之前是可变还是不可变;mutableCopy得到的总是可变对象,不管之前是可变还是不可变

  1. NSString *string = @"123456";
  2. //没有产生新对象
  3. NSString *copyString = [string copy];
  4. //产生新对象
  5. NSString *mutableString = [string mutableCopy];
  6. NSLog(@"string=%p copyString=%p mutableString=%p", string, copyString, mutableString);

打印结果:

  1. string=0x1024b5068 copyString=0x1024b5068 mutableString=0x600000262980

小结:对NSString对象进行copy只是浅拷贝,并不会产生新的对象;对NSString对象进行mutableCopy是深拷贝,会产生新的对象

  1. NSMutableString *string = [NSMutableString stringWithFormat:@"123456"];
  2. //产生新对象
  3. NSString *copyString = [string copy];
  4. //产生新对象
  5. NSMutableString *mutableString = [string mutableCopy];
  6. NSLog(@"string=%p copyString=%p mutableString=%p", string, copyString, mutableString);

打印结果:

  1. string=0x60800007ce40 copyString=0xa003635343332316 mutableString=0x60800007d080

小结:对NSMutableString对象进行copy和mutableCopy都是深拷贝,都会产生新的对象

总结:对于不可变对象的copy是浅拷贝,mutableCopy是深拷贝;对于可变对象的copy和mutableCopy都是深拷贝

(四)自定义对象的copy

  1. @interface Person : NSObject <NSCopying>
  2. @property (nonatomic, copy) NSString *name;
  3. @property (nonatomic, assign) int age;
  4. @end
  1. reason: '-[Person copyWithZone:]: unrecognized selector sent to instance 0x608000024f80'
  1. - (id)copyWithZone:(NSZone *)zone
  2. {
  3. Person *p = [[Person allocWithZone:zone] init];
  4. return p;
  5. }
  1. - (void)test1
  2. {
  3. Person *p = [[Person alloc] init];
  4. p.name = @"jack";
  5. p.age = 18;
  6. Person *copyP = [p copy];
  7. //产生了新对象,深拷贝
  8. NSLog(@"p=%p copyP=%p", p, copyP);
  9. NSLog(@"name=%@ age=%d", copyP.name, copyP.age);
  10. }
  1. - (id)copyWithZone:(NSZone *)zone
  2. {
  3. Person *p = [[Person allocWithZone:zone] init];
  4. p.name = self.name;
  5. p.age = self.age;
  6. return p;
  7. }

小结:当自定义对象调用copy时,会产生新对象,属于深拷贝

(五)NSString使用copy和strong的区别

1. copy

  1. @interface Person : NSObject
  2. @property (nonatomic, copy) NSString *name;
  3. @end
  1. NSMutableString *string = [NSMutableString stringWithFormat:@"jack"];
  2. Person *p = [[Person alloc] init];
  3. p.name = string;
  4. [string appendString:@"123"];
  5. NSLog(@"%@", p.name);
  1. @property (nonatomic, copy) NSString *name;
  2. //当调用上面的copy的时候,等价于下面的代码
  3. - (void)setName:(NSString *)name
  4. {
  5. if (_name != name) {
  6. [_name release];
  7. _name = [name copy];
  8. }
  9. }

2. strong

  1. @interface Person : NSObject
  2. @property (nonatomic, strong) NSString *name;
  3. @end
  1. NSMutableString *string = [NSMutableString stringWithFormat:@"jack"];
  2. Person *p = [[Person alloc] init];
  3. p.name = string;
  4. [string appendString:@"123"];
  5. NSLog(@"%@", p.name);
  1. @property (nonatomic, strong) NSString *name;
  2. //当调用上面的strong时,等价于下面代码
  3. - (void)setName:(NSString *)name
  4. {
  5. _name = name;
  6. }

对NSString使用copy是用来保护其封装性,因为传递给设置方法的新值可能是NSMutableString类型,此时若不拷贝字符串,那么设置完属性之后,字符串的值就可能会在对象不知情的情况下遭人更改。所以,这时就要拷贝一份不可变的字符串,确保对象中的字符串不会无意间改动。只要实现属性所用的对象是可变的,就应该在设置新属性值时拷贝一份

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注