系统的对象
先看看我的测试代码,一切按照事实说话,我觉得是最有权威的。
NSString *name = @"张三";
//浅复制
NSString *copyName = [name copy];
//深复制
NSMutableString *mutableName = [name mutableCopy];
NSLog(@"name = %p copyName = %p mutableName = %p", name, copyName, mutableName);
// name = 0x108ff6068 copyName = 0x108ff6068 mutableName = 0x60000006dbc0
NSMutableString *company = [[NSMutableString alloc]initWithString:@"中天"];
//浅复制
NSString *copyCompany = [company copy];
//深复制
NSString *mutableCompany = [company mutableCopy];
NSLog(@"company = %p copyCompany = %p mutableCompany = %p", company, copyCompany, mutableCompany);
//company = 0x600000072080 copyCompany = 0x600000035d20 mutableCompany = 0x600000072200
总结:对于系统的对象copy出来的永远是不可变对象,mutableCopy出来的永远是可变对象。
自定义对象
Car *car = [[Car alloc]init];
car.name = @"迈腾";
//, reason: '-[Car copyWithZone:]: unrecognized selector sent to instance 0x6000000090b0'
Car *copyCar = [car copy];
直接copy还会报错,得实现copyWithZone方法。
#import "Car.h"
@interface Car()
@end
@implementation Car
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
- (id)copyWithZone:(NSZone *)zone
{
Car *car = [[Car allocWithZone:zone] init];
return Car;
// 有些人可能下面alloc,重新初始化空间,但这方法已给你分配了zone,自己就无需再次alloc内存空间了
// Car *car = [[Car alloc] init];
}
@end
结论:这个自定义的对象,要实现copy,首先遵守NSCopying协议,然后实现- (id)copyWithZone:(NSZone *)zone,它里头的实现不一样出的结果不一样,return self,就不会拷贝空间,第二种的重新创建个对象返回肯定要分配新的空间。
property里NSString用什么修饰copy OR strong
我想了三种情况:
@interface Car : NSObject
@property(nonatomic,copy)NSString *name;
@property(nonatomic,strong)NSString *company;
@property(nonatomic,copy)NSMutableString *city;
@end
Car *car = [[Car alloc]init];
NSMutableString *name = [NSMutableString stringWithString:@"王"];
car.name = name;
[name appendString:@"哈哈"];
//2017-07-11 14:10:02.434 copy[7295:219183] 王
NSLog(@"%@",car.name);
NSMutableString *company = [NSMutableString stringWithString:@"中天"];
car.company = company;
[company appendString:@"哈哈"];
//2017-07-11 14:12:39.283 copy[7364:221097] 中天哈哈
NSLog(@"%@",car.company);
NSMutableString *city = [NSMutableString stringWithString:@"中国"];
car.city = city;
//reason: 'Attempt to mutate immutable object with appendString:'奔溃
[car.city appendString:@"哈哈"];
解释一下,第一种是对的,copy的是不可变对象,即使之前的增加也不会影响到自己。第二种就是指针指到同一个地址了。之前的变化会影响到自己。最后一种本来就是错的,copy的是不可变对象,但是用NSMutableString来接,给人错觉,以为真的可以加字符串,导致程序奔溃。