iOS的copy和mutableCopy

系统的对象

先看看我的测试代码,一切按照事实说话,我觉得是最有权威的。

     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出来的永远是可变对象。
iOS的copy和mutableCopy_第1张图片
295346-bd95431918be69b1.png

自定义对象

   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来接,给人错觉,以为真的可以加字符串,导致程序奔溃。

结论:一般开发正确的写法是@property(nonatomic,copy)NSString *name;

你可能感兴趣的:(iOS的copy和mutableCopy)