情况一(@property (nonatomic,copy)NSString *str;)(@property (nonatomic,strong)NSString *str;)self. str = NSString(实例)
@interface ViewController ()
@property (nonatomic,copy)NSString *str;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *base_str = @"我是";//实例化分配堆内存
self.str = base_str;//copy对NSString只是指针拷贝(浅拷贝)
NSLog(@"str--%p+++%@",self.str,self.str);//0x1006a4020+++我是
NSLog(@"base_str--%p+++%@",base_str,base_str);//0x1006a4020+++我是
NSLog(@"分割线---------------------------------------------");
base_str = @"haha";//重新实例化重新分配堆内存(但是对原来的地址不影响)
NSLog(@"str--%p+++%@",self.str,self.str);//0x1006a4020+++我是
NSLog(@"base_str--%p+++%@",base_str,base_str);//0x1006a40a0+++haha
}
2021-03-22 16:22:42.509744+0800 IOS--多继承[36010:335669] str--0x1006a4020+++我是
2021-03-22 16:22:42.509955+0800 IOS--多继承[36010:335669] base_str--0x1006a4020+++我是
2021-03-22 16:22:42.510093+0800 IOS--多继承[36010:335669] 分割线---------------------------------------------
2021-03-22 16:22:42.510221+0800 IOS--多继承[36010:335669] str--0x1006a4020+++我是
2021-03-22 16:22:42.510330+0800 IOS--多继承[36010:335669] base_str--0x1006a40a0+++haha
情况二(@property (nonatomic,copy)NSString *str;)self. str = NSMutableString(实例)
@interface ViewController ()
@property (nonatomic,copy)NSString *str;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableString *m_str = [NSMutableString stringWithString:@"nihao"];
self.str = m_str;//copy对NSMutableString生成了新的地址(深拷贝)
NSLog(@"str--%p+++%@",self.str,self.str);//0xbe2d07ae3dfa791b+++nihao
NSLog(@"m_str--%p+++%@",m_str,m_str);//0x600000558870+++nihao
NSLog(@"分割线---------------------------------------------");
[m_str appendFormat:@"修改后"];
NSLog(@"str--%p+++%@",self.str,self.str);//0xdb33f1772ec1e5d1+++nihao
NSLog(@"m_str--%p+++%@",m_str,m_str);//0x600000724db0+++nihao修改后
}
情况三(@property (nonatomic,strong)NSString *str;)self. str = NSMutableString(实例)
@interface ViewController ()
@property (nonatomic,strong)NSString *str;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableString *m_str = [NSMutableString stringWithString:@"nihao"];
self.str = m_str;//strong对NSMutableString没有生成了新的地址(浅拷贝)
NSLog(@"str--%p+++%@",self.str,self.str);//0xbe2d07ae3dfa791b+++nihao
NSLog(@"m_str--%p+++%@",m_str,m_str);//0x600000558870+++nihao
NSLog(@"分割线---------------------------------------------");
[m_str appendFormat:@"修改后"];
NSLog(@"str--%p+++%@",self.str,self.str);//0xdb33f1772ec1e5d1+++nihao
NSLog(@"m_str--%p+++%@",m_str,m_str);//0x600000724db0+++nihao修改后
}
2021-03-22 16:39:20.728281+0800 IOS--多继承[36287:351536] str--0x60000235e3d0+++nihao
2021-03-22 16:39:20.728446+0800 IOS--多继承[36287:351536] m_str--0x60000235e3d0+++nihao
2021-03-22 16:39:20.728574+0800 IOS--多继承[36287:351536] 分割线---------------------------------------------
2021-03-22 16:39:20.728697+0800 IOS--多继承[36287:351536] str--0x60000235e3d0+++nihao修改后
2021-03-22 16:39:20.728811+0800 IOS--多继承[36287:351536] m_str--0x60000235e3d0+++nihao修改后
情况四(@property (nonatomic,strong)NSMutableString *m_str;)self.m_str = NSString
@interface ViewController ()
@property (nonatomic,strong)NSMutableString *m_str;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *str = @"nihao";
self.m_str = str;//strong对str只是引用计数+1(此时self.m_str还是不可变NSString)
NSLog(@"str--%p+++%@",str,str);
NSLog(@"m_str--%p+++%@",self.m_str,self.m_str);
NSLog(@"分割线---------------------------------------------");
str = @"修改后";
[self.m_str appendFormat:@"修改"];//(编译能通过,运行时候Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to mutate immutable object with appendFormat:'*** First throw call stack:)
//因为appendFormat是NSMutableString的方法
NSLog(@"str--%p+++%@",str,str);
NSLog(@"m_str--%p+++%@",self.m_str,self.m_str);
}
@interface ViewController ()
@property (nonatomic,copy)NSMutableString *m_str;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableString *str = [NSMutableString stringWithString:@"nihao"];
self.m_str = str;//strong对str只是引用计数+1(此时self.m_str还是不可变NSString)
NSLog(@"str--%p+++%@",str,str);
NSLog(@"m_str--%p+++%@",self.m_str,self.m_str);
NSLog(@"分割线---------------------------------------------");
[self.m_str appendFormat:@"修改"];//(编译能通过,运行时候Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to mutate immutable object with appendFormat:'*** First throw call stack:)
//因为appendFormat是NSMutableString的方法
NSLog(@"str--%p+++%@",str,str);
NSLog(@"m_str--%p+++%@",self.m_str,self.m_str);
}
当使用 strong 修饰属性的时候,属性的setter方法会直接强引用该对象,这样,当原object对象的值发生改变时,新对象的属性也改变;
但是对于可变对象类型,如NSMutableString、NSMutableArray等则不可以使用copy修饰,因为Foundation框架提供的这些类都实现了NSCopying协议,使用copy方法返回的都是不可变对象,如果使用copy修饰符在对可变对象赋值时则会获取一个不可变对象,接下来如果对这个对象进行可变对象的操作则会产生异常,因为OC没有提供mutableCopy修饰符,对于可变对象使用strong修饰符即可。
总结:
针对不可变对象使用copy修饰,针对可变对象使用strong修饰。