文档原文,实现的规范

 

  1. Your options for implementing this protocol are as follows: 
  2.  
  3. Implement NSCopying using alloc and init... in classes that don’t inherit copyWithZone:. 
  4. Implement NSCopying by invoking the superclass’s copyWithZone: when NSCopying behavior is inherited. If the superclass implementation might use the NSCopyObject function, make explicit assignments to pointer instance variables for retained objects. 
  5. Implement NSCopying by retaining the original instead of creating a new copy when the class and its contents are immutable. 

1.如果这个类不是从一个已经实现NSCopying协议的类继承而来那么它应该使用

[[ alloc]init]创建对象,初始化后返回。

2.如果它是从一个已经实现NSCopying协议的类继承来,那么它应该调用[super copyWithZone]方法。如果父类使用NSCopyObject方法,那么直接创建一个引用接收它。

3.如果父类已经实现NSCopying协议,且数据是不可变长的,那么直接创建一个引用接收它,不要再创建一个新的对象了。

总结:

其实这些原则从很大程序上来讲是为了避免内存泄漏,和提高效率降低出错率。

 

引用一下一个例子:

 

 
  1. You should always use [[self class] allocWithZone:zone] to make sure you are creating a copy using the appropriate class. The example you give for 002 shows exactly why: Subclasses will call [super copyWithZone:zone] and expect to get back an instance of the appropriate class, not an instance of the super class.

  2. I access the ivars directly, so I don't need to worry about any side effects I might add to the property setter (e.g., generating notifications) later on. Keep in mind, subclasses are free to override any method. In your example, you are sending two extra messages per ivar. I would implement it as follows:

Code:

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

Of course, whether you copy the ivars, retain them, or just assign them should mirror what the setters do.