NSCopying和NSMutableCopying

 以前一直对NSCopying和NSMutableCopying两个类比较陌生,为了深入理解,做笔记如下,笔记会分一个概述和四个小节来进行讲解:
NSCopying是一个Foundation框架的基本协议,所有的NSObject以及其子类都遵守这个协议。遵守这个协议的类都需要重写- (id)copyWithZone:这个方法,区别在于系统的类会由系统来重写代理方法,而自定义的类需要我们手动重写代理方法,如果不进行重写系统会crash掉。NSMutableCopying与NSCopying类似,需要重写- (id)mutableCopyWithZone:。
1.非集合类:
```objc
  NSString *str = @"test";
  NSString *strCopy = [str copy];
  NSMutableString *mutableStrCopy = [str mutableCopy];

  NSLog(@"%p",str);
  NSLog(@"%p",strCopy);
  NSLog(@"%p",mutableStrCopy);
```
打印结果如下:
   MasonryTest[1368:150492] 0x10bc34220
   MasonryTest[1368:150492]  0x10bc34220
   MasonryTest[1368:150492] 0x60800007b300
可以看出strCopy对str进行了指针拷贝,mutableStrCopy对str进行了内容。然后我们将strCopy声明为NSMutableString,调用appendString方法:
  NSMutableString *mStrCopy = [str copy];
  [mStrCopy appendString:@"test"]; // crash

原因在于copy返回的对象是不可变的,强制调用appendString方法,在运行时的时候无法再方法列表中找到方法,所以crash
集合类:
2.不可变的集合类:
NSArray *arr = @[@"zhangsan",@"lisi"];
NSMutableArray *arrCopy = [arr copy];
NSMutableArray *mutableArrCopy = [arr mutableCopy];

NSLog(@"%p",arr);
NSLog(@"%p",arrCopy);
NSLog(@"%p",mutableArrCopy);

运行结果为:
MasonryTest[1502:163348] 0x600000037e80
MasonryTest[1502:163348] 0x600000037e80
MasonryTest[1502:163348] 0x60000004f2d0
由此可见copy对不可变的集合类进行了指针拷贝,mutableCopy对不可变的集合类进行了内容拷贝
可变的集合类:
NSMutableArray *arr = [[NSMutableArray alloc]initWithArray:@[@"zhangshan",@"lisi"]];
NSArray *arrCopy = [arr copy];
NSMutableArray *mutableArrCopy = [arr mutableCopy];

NSLog(@"%p",arr);
NSLog(@"%p",arrCopy);
NSLog(@"%p",mutableArrCopy);

运行结果:
MasonryTest[1544:169111] 0x60800005f5f0
MasonryTest[1544:169111] 0x608000039b80
MasonryTest[1544:169111] 0x608000058fc0
可见可变的集合类进行无论进行copy还是mutableCopy实质上都进行了内容拷贝
3.自定义对象:
Person *person = [[Person alloc]init];
Person *personCopy = [person copy]; // crash
Person *personMutableCopy = [person mutableCopy]; // crash
原因是自定义对象没有实现- (id)copyWithZone:和- (id)mutableCopyWithZone:方法

  • (id)copyWithZone:(NSZone *)zone {

    Person *person = [[[self class] allocWithZone:zone] init];
    return person;
    }

  • (id)mutableCopyWithZone:(NSZone *)zone{

    Person *person = [[[self class] allocWithZone:zone] init];
    return person;
    }
    重写方法后运行结果为:
    MasonryTest[1763:186469] 0x60000000a3c0
    MasonryTest[1763:186469] 0x60000000a450
    MasonryTest[1763:186469] 0x60000000a480
    由此可见无论是copy还是mutableCopy都对自定义对象进行了内容拷贝

你可能感兴趣的:(NSCopying和NSMutableCopying)