iphone - 实现 copyWithZone : 时的最佳实践

我正在努力澄清一些关于实现 copyWithZone: 的事情,任何人都可以评论以下内容...

// 001: Crime is a subclass of NSObject.
- (id)copyWithZone:(NSZone *)zone {
    Crime *newCrime = [[[self class] allocWithZone:zone] init];
    if(newCrime) {
        [newCrime setMonth:[self month]];
        [newCrime setCategory:[self category]];
        [newCrime setCoordinate:[self coordinate]];
        [newCrime setLocationName:[self locationName]];
        [newCrime setTitle:[self title]];
        [newCrime setSubtitle:[self subtitle]];
    }
    return newCrime;
}

// 002: Crime is not a subclass of NSObject.
- (id)copyWithZone:(NSZone *)zone {
    Crime *newCrime = [super copyWithZone:zone];
    [newCrime setMonth:[self month]];
    [newCrime setCategory:[self category]];
    [newCrime setCoordinate:[self coordinate]];
    [newCrime setLocationName:[self locationName]];
    [newCrime setTitle:[self title]];
    [newCrime setSubtitle:[self subtitle]];
    return newCrime;
}

在 001 中:

  1. 类名最好直接写[[Crime allocWithZone:zone] init]还是应该使用[[[self Class] allocWithZone:zone] init] ?

  2. 可以使用 [self month] 来复制 iVar 还是我应该直接访问 iVar,即 _month

最佳答案

  1. 您应该始终使用 [[self class] allocWithZone:zone] 来确保使用适当的类创建副本。您为 002 提供的示例确切说明了原因:子类将调用 [super copyWithZone:zone] 并期望返回适当类的实例,而不是父类(super class)的实例。

  2. 我直接访问 ivars,所以我不需要担心我以后可能会添加到属性 setter (例如,生成通知)的任何副作用。请记住,子类可以自由地覆盖任何方法。在您的示例中,您为每个 ivar 发送两条额外的消息。我将按如下方式实现:

代码:

- (id)copyWithZone:(NSZone *)zone {
    Crime *newCrime = [super copyWithZone:zone];
    newCrime->_month = [_month copyWithZone:zone];
    newCrime->_category = [_category copyWithZone:zone];
    // etc...
    return newCrime;
}

当然,无论您是复制 ivars、保留它们,还是仅仅分配它们,都应该反射(reflect) setter 所做的事情。

https://stackoverflow.com/questions/9907154/

相关文章:

ios - 是否可以调试 "Terminated due to memory error"?

objective-c - 在 Objective-C 中从字符串中删除空格

ios - 如何检查是否为 64 位构建了静态库?

ios - 如何为 NSDate 添加一个月?

ios - 找不到符号 : kUTTypeImage

objective-c - 删除 NSString 的最后一个字符

ios - 在主线程上调用方法?

iphone - iOS 7 UIRefreshControl tintColor 不适用于 beg

ios - NSPredicate 用于测试 NULL 和空白字符串

ios - 如何调用 iPhone map 以获取当前位置作为起始地址的方向