// // main.m // Copy基本使用,拷贝的本质:修改其中一个不能影响另外一个。 // 每个oc对象都有copy和mutableCopy方法,前提是必须遵守NSCopying协议实现copyWithZone方法和NSMutableCopying协议实现mutableCopyWithZone方法。 // copy出来的对象是不可变的(NSString,NSArray,NSDictionary),NSMutableString调用copy方法出来的是NSString,mutableCopy出来的对象是可变的(NSMutableString,NSMutableArray,NSMutableDictionary).NSString调用mutableCopy方法出来的是NSMutableString。 // oc大部分对象都遵循了NSCopying和NSMutableCopying协议,自定义对象是没有copy和mutableCopy方法的。 // #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { // 会生成一个新的对象 NSString *srcStr1 = @"lnj"; // 只要是拷贝出来的对象, 拷贝出来的对象中的内容和以前对象中的内容一致 // "一般"情况下拷贝会生成一个新的对象 // 为什么会产生一个新的对象 1.因为拷贝要求修改原来的对象不能影响到拷贝出来得对象 修改拷贝出来的对象也不能影响到原来的对象, 所以需要生成一个新的对象 2.由于以前的对象是一个不可变的对象, 而通过mutableCopy拷贝出来的对象必须是一个可变的对象, 所以必须生成一个新的对象 NSMutableString *copyStr1 = [srcStr1 mutableCopy]; NSLog(@"srcStr = %@, copyStr = %@", srcStr1, copyStr1); NSLog(@"srcStr = %p, copyStr = %p", srcStr1, copyStr1);//srcStr = 0x100004238, copyStr = 0x100700090 // 会生成一个新的对象 NSMutableString *srcStr2 = [NSMutableString stringWithFormat:@"lnj"]; NSMutableString *copyStr2 = [srcStr2 mutableCopy]; [srcStr2 appendString:@" cool"]; NSLog(@"srcStr = %@, copyStr = %@", srcStr2, copyStr2); NSLog(@"srcStr = %p, copyStr = %p", srcStr2, copyStr2);//srcStr = 0x100300560, copyStr = 0x100202780 // 会生成一个新的对象 NSMutableString *srcStr3 = [NSMutableString stringWithFormat:@"lnj"]; NSString *copyStr3 = [srcStr3 copy]; [srcStr3 appendString:@" cool"]; NSLog(@"srcStr = %@, copyStr = %@", srcStr3, copyStr3); NSLog(@"srcStr = %p, copyStr = %p", srcStr3, copyStr3);//srcStr = 0x100204aa0, copyStr = 0x6a6e6c35 //不生成新的对象 // 如果是通过不可变对象调用了copy方法, 那么不会生成一个新的对象(2个都是不可变的,那么可以公用一个算了,只要有一个是可变的,那么修改一个就会影响另外一个,所以不能指向同一个内存空间)。 // 原因: 因为原来的对象是不能修改的, 拷贝出来的对象也是不能修改的,既然两个都不能修改, 所以永远不能影响到另外一个对象, 那么已经符合需求,所以: OC为了对内存进行优化, 就不会生成一个新的对象 NSString *srcStr = @"lnj"; NSString *copyStr = [srcStr copy]; NSLog(@"srcStr = %p, copyStr = %p", srcStr, copyStr);//srcStr = 0x100004238, copyStr = 0x100004238 /* 正是因为调用copy方法有时候会生成一个新的对象, 有时候不会生成一个新的对象 所以: 如果没有生成新的对象, 我们称之为浅拷贝, 本质就是指针拷贝 如果生成了新的对象, 我们称之为深拷贝, 本质就是会创建一个新的对象 */ return 0; }