Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

liruqi
Copy link

@liruqi liruqi commented Oct 29, 2015

文中的 - 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 也会出错。

文中的 `- 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

```
首先,if 的确比对象 copy 要快。
另外,判断对象是否相同是为了保证代码执行的正确性。在非 ARC 环境下,如果穿入对象 retain count 为 1,不做判断的话,release 之后对象内存释放,下一步 copy 也会出错。
更新 *重写带 copy 关键字的 setter* 的答案
@liruqi liruqi changed the title 删除关于深拷贝相关的描述和代码 更新问题 “如何让自己的类用 copy 修饰符?如何重写带 copy 关键字的 setter?” 的答案 Oct 29, 2015
@Vera2016
Copy link

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

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants