iOSInterviewQuestions icon indicating copy to clipboard operation
iOSInterviewQuestions copied to clipboard

更新问题 “如何让自己的类用 copy 修饰符?如何重写带 copy 关键字的 setter?” 的答案

Open liruqi opened this issue 10 years ago • 1 comments

文中的 - deepCopy 方法并不能实现深拷贝。

CYLUser- copyWithZone 方法里,_friends 成员的的赋值使用的 - mutableCopy 是浅拷贝,只是创建了NSMutableSet 对象;导致 - deepCopy方法中, _friends 的每一个对象的 _friends 列表并未创建实例。

为了测试 NSArray, NSSet 容器类初始化行为,我写了测试代码,

    NSMutableArray *objects = [NSMutableArray array];
    [objects insertObject:[NSDate date] atIndex:0];

    if ([objects count] > 0) {
        NSArray *arr = [[NSArray alloc] initWithArray: objects];
        for (int i=0; i<arr.count; i++) {
            NSLog(@"%d %x %x", i, (uint) objects[i], (uint)arr[i]);
        }

        NSMutableSet* set = [[NSMutableSet alloc] initWithArray: objects];
        NSMutableSet* setcopy = [set mutableCopy];
        NSLog(@"set 1: %@ %x", set, (uint) [set allObjects][0]);
        NSLog(@"set 2: %@ %x", setcopy, (uint) [setcopy allObjects][0]);
    } 

执行结果:

2015-10-29 17:44:29.240 NSSpec[12024:438388] 0 2a43ec60 2a43ec60
2015-10-29 17:44:29.241 NSSpec[12024:438388] set 1: {(
    2015-10-29 09:44:26 +0000
)} 2a43ec60
2015-10-29 17:44:29.241 NSSpec[12024:438388] set 2: {(
    2015-10-29 09:44:26 +0000
)} 2a43ec60

关于 如何重写带 copy 关键字的 setter

首先,if 的确比对象 copy 要快。 另外,判断对象是否相同是为了保证代码执行的正确性。在非 ARC 环境下,如果穿入对象 retain count 为 1,不做判断的话,release 之后对象内存释放,下一步 copy 也会出错。

liruqi avatar Oct 29 '15 10:10 liruqi

您的文章里有这么一句话,我有点疑问: ”CYLUser 的 - copyWithZone 方法里,_friends 成员的的赋值使用的 - mutableCopy 是浅拷贝,只是创建了NSMutableSet 对象;导致 - deepCopy方法中, _friends 的每一个对象的 _friends 列表并未创建实例。“ 我的观点是导致 ‘ 导致- deepCopy方法中, _friends 的每一个对象的 _friends 列表并未创建实例’ 的原因应该是,_friends 的每一个对象是否实现了NSCopying协议,与‘CYLUser 的 - copyWithZone 方法’ 没有关系。

希望您能回复我,我这有点蒙圈了,谢谢

Vera2016 avatar Dec 20 '21 03:12 Vera2016