Objective-C Copy的概念、入门和内存管理

1、对象copy概念
  使用copy 会产生一个副本
  
  修改副本,不会改变原对象
  
  OC中的copy,就是指的是对象的拷贝
  
  使用copy功能
  需要遵守NSCopying协议,实现copyWithZone:方法  
  copy : 创建一个不可变副本(如NSString、NSArray、NSDictionary)
         copy的对象是不可变 那么copy出来的就是不可变副本
  mutableCopy: 创建的是可变副本(如NSMutableString、NSMutableArray、NSMutableDictioanry)
        
  
  创建一个mac项目
  @autoreleasepool{
      Dog *d = [Dog new];
 //Dog *d2 = [d copy];//这是错误的写法
  
     //例如
     //NSString 遵守了NSCopying协议和NSMutableCopying协议  
  
  }
  
  
  创建一个IOS项目
  NSString *str = @"abc";
  NSLog(@"str = %@  str's addr = %p",str,str);
  
  NSString *str2 = [str copy];
  NSLog(@"str2 = %@  str's addr = %p",str str);
  
  NSMutableString *mstr = [NSMutableString string];
  [mstr appendString:@"abc"];
  
  NSMutableString *mstr2 = [mstr copy];
  [mstr2 appendString:@"xxxxx"];
  
  NSLog(@"mstr2 = %@", mstr2);//输出abcxxxxx
  
  
  注意:mutableCopy就是深复制,会再内存中重新分配一块内存空间
  
  
  
2.  深拷贝和浅拷贝   内存管理
   //在IOS项目中
   //创建一个字符串,copy一个不可变副本
   NSString *str = [NSString stringWithFormat:@"abc"]; //1
   NSString *str2 = [str copy];//2
   
   NSLog(@"str.retainCount = %lu  str addr = %p",str.retainCount, str);
   NSLog(@"str2.retainCount = %lu  str2 addr = %p",str2.retainCount, str2);
   //打印出来后,str和str2的内存地址是一样的,str2的引用计数是2,str的引用计数是1,这就是浅拷贝
   
   //mutableCopy一个可变的副本
   NSMutableString *str3 = [str mutableCopy];
   NSLog(@"str3.retainCount = %lu  str3 addr = %p",str3.retainCount,str3);
   NSLog(@"str.retainCount = %lu  str addr = %p",str.retainCount,str);
   //打印出来后,str和str3是在两块内存存储,各自的引用计数为1,这就是深拷贝
   
   
   
   copy与内存管理
   1.深复制 (深拷贝,内容拷贝,deep copy)
      1) 源对象和副本对象是不同的两个对象
      2) 源对象引用计数器不变,副本对象计数器为1(因为它是新产生的)
  
   2.浅复制(浅拷贝,指针拷贝,shaddow copy)
     1) 源对象和副本对象是同一个对象
2) 源对象(副本对象)引用计数器 +1 相当于做了一次retain操作
   本质没有产生新的对象
  
  
  
  
  
  
  
  
  
  
  
  
  
3. @Property中的copy关键字
  
   在MRC机制下,成员变量如果是OC对象类型,
   那么必须重写dealloc方法,在dealloc方法里,
   将该这个OC对象发送一次release
   @property (nonatomic,retain) NSString *name;
   
   
   
   Person *p = [Person new];
   
   //1
   p.name = @"john";
   NSLog(@"p.name = %@",p.name);
   
   //2
   NSMutableString *mstr = [NSMutableString string];
   [mstr appendString:@"john silver"];
   p.name = mstr;
   NSLog(@"p.name = %@", mstr);//打印john silver
   
   [mstr appendString:@"&ken"];
   NSLog(@"p.name = %@", p.name);//打印john silver&ken


   这肯定是不行的,我要改成&ken 它变成john silver&ken
   
   所有我们把成员变量改成
   @property (nonatomic,copy) NSString *name;
   并且在dealloc方法里发送release消息
   [_name release];
   
   
   
   
 @property内存管理策略和选择
 1.MRC机制下
   1) copy : 只用于NSString\Block
   2) retain: 除了NSString\Block以外的OC对象
   3) assign: 基本数据类型,枚举,结构体(非OC对象),当2个对象相互引用,一端用
   
 2.ARC机制下
   1) copy : 只用于NSString\block
   2) strong:除NSString\block以外的OC对象
   3) weak : 当2个对象相互引用,一端用strong,一端用weak
   4) assign:基本数据类型,枚举,结构体(非OC对象)
   
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
4.为自定义的类实现copy操作
  步骤:
  1.让Person类遵守NSCopying协议
  2.实现copyWithZone:方法 ,在该方法中返回一个对象的副本即可
  3.在copyWithZone方法中,创建一个新的对象,并设置该对象的数据与现有对象一致,并返回该对象
  4.创建Person对象,调用copy方法,查看地址


  @interface Person : NSObject<NSCopying,NSMutableCopying>
  @property (nonatomic,assign) int age;
  @property (nonatomic,assign) int height;
  @end
  @implementation Person
  //当我们每次调用copy,系统就会帮我们处理copyWithZone方法
  //该方法就是创建一个新的对象,对象里的值和当前调用该方法的对象保持一致,并将它返回
  //自定义对象的copy都是深拷贝 
  -(id)copyWithZone:(NSZone*)zone{
 Person *p = [[Person alloc] init];
 p.age = self.age;
 p.height = self.height;
 return p;
  }
  @end
  
  int main(){
     Person *p = [Person new];
p.age = 22;
p.height = 180;
NSLog(@"p.age = %d, p.height = %d", p.age, p.height);
 
     Person *p1 = [p copy];
NSLog(@"p1.age = %d, p1.height = %d", p1.age, p1.height);
     
//这样就达到了自定义copy,这种是深拷贝,两个对象完全不一样
return 0;
  }
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值