美文网首页
iOS copy与mutableCopy的区别

iOS copy与mutableCopy的区别

作者: 雪贝壳 | 来源:发表于2023-02-14 11:48 被阅读0次

拷贝方法分两种:copy和muutableCopy
一般只有Foundation框架自带的一些类才具有区分可变/不可变的能力,如:字符串、数组、字典等。这些类在使用copy和muutableCopy时有区别,返回可能是可变/不可变的对象。
其他类不区分是否可变,如:自定义的类,UIKit框架下的类。这些类在使用copy和muutableCopy时没有区别,返回的都是可变对象。

区分可变/不可变的拷贝

区分可变/不可变的类有以下几种:

字符串:NSString NSMutableString
数组:NSArray NSMutableArray
字典:NSDictionary NSMutableDictionary
数据:NSData NSMutableData
集合:NSSet NSMutableSet

拷贝类型分深拷贝和浅拷贝
深拷贝:拷贝源对象生成副本对象,两者在不同的内存。对不可变类型调用mutableCopy、可变类型调用copy和mutableCopy都是深拷贝。
浅拷贝:不拷贝源对象,不会生成副本对象,只拷贝指向源对象的指针。对不可变对象调用copy方法的情况就是浅拷贝。

mutableCopy返回的是可变对象。

案例分析

1.copy

copy返回的是不可变对象
调用copy拷贝不可变对象例子:

NSDictionary *dic1 = @{@"key1":@"value1"};
NSDictionary *dic2 = [dic1 copy];
// 打印结果:0x10aeb37e8,0x10aeb37e8
// 两者地址相同,指向同一个对象,为浅拷贝
NSLog(@"%p,%p",dic1,dic2);
    
//修改dic2 报错崩溃 *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<NSConstantDictionary 0x10aeb37e8> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key key2.'
[dic2 setValue:@"value2" forKey:@"key2"];

调用copy拷贝可变对象例子:

NSMutableDictionary *dic1 = [NSMutableDictionary dictionaryWithObject:@"value1" forKey:@"key1"];
NSDictionary *dic2 = [dic1 copy];
// 打印结果:0x600001374060,0x6000013740a0,{ key1 = value1;},{key1 = value1;}
// 两者地址不同,内容相同,为深拷贝,返回的是不可变对象
NSLog(@"%p,%p,",dic1,dic2);
    
//修改dic2 报错崩溃 *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSFrozenDictionaryM 0x60000079f760> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key key2.'
[dic2 setValue:@"value2" forKey:@"key2"];
2.mutableCopy

mutableCopy返回的是可变对象。
调用mutableCopy拷贝不可变对象例子:

NSDictionary *dic1 = @{@"key1":@"value1"};
NSDictionary *dic2 = [dic1 mutableCopy];
// 打印结果:0x105c9c7e8,0x600003ec5760,{key1 = value1;},{key1 = value1;}
// 两者地址不同,内容相同,为深拷贝
NSLog(@"%p,%p,%@,%@",dic1,dic2,dic1,dic2);
    
// 返回的是可变对象 修改dic2,修改成功
[dic2 setValue:@"value2" forKey:@"key2"];

调用mutableCopy拷贝可变对象例子:

NSMutableDictionary *dic1 = [NSMutableDictionary dictionaryWithObject:@"value1" forKey:@"key1"];
NSDictionary *dic2 = [dic1 mutableCopy];
// 打印结果:0x6000001109e0,0x600000110b20,{key1 = value1;},{key1 = value1;}
// 两者地址不同,内容相同,为深拷贝

NSLog(@"%p,%p,%@,%@",dic1,dic2,dic1,dic2);
    
// 返回的是可变对象 修改dic2,修改成功
[dic2 setValue:@"value2" forKey:@"key2"];

不区分可变/不可变的拷贝

其他类是不区分是否可变的,如:自定义类、UIKit框架下的类。
拷贝类型只有深拷贝,没有浅拷贝,使用copy和mutableCopy没有区别,返回的都是可变对象。使用时,需要先遵循NSCoping或NSMutableCopying协议。

@interface Person : NSObject<NSCopying,NSMutableCopying>
@property (nonatomic,copy) NSString * name;
@property (nonatomic,strong) NSMutableArray *maryDatas;
@end

@implementation Person
- (id)copyWithZone:(NSZone *)zone {
    Person *person = [Person allocWithZone:zone];
    person.name = self.name;
    person.maryDatas = [self.maryDatas mutableCopy];
    return person;
}

- (id)mutableCopyWithZone:(NSZone *)zone {
    Person *person = [Person allocWithZone:zone];
    person.name = self.name;
    person.maryDatas = [self.maryDatas mutableCopy];
    return person;
}
@end

// 示例:
- (void)test {
    Person *person1 = [[Person alloc] init];
    person1.name = @"jack";
    person1.maryDatas = [NSMutableArray arrayWithObject:@"1"];
    
    Person *person2 = [person1 copy];
    person2.name = @"bela";
}

相关文章

网友评论

      本文标题:iOS copy与mutableCopy的区别

      本文链接:https://www.haomeiwen.com/subject/fywjkdtx.html