Chapter 13 Protocols
A formal protocol is a named list of methods.
You adopt a protocol by listing the protocol’s name in your class’s @interface declaration. When you do this, your class is said to conform to the protocol
Formal protocols are just like Java interfaces.
Declaring Protocols
@protocol NSCopying
- (id) copyWithZone: (NSZone *) zone;
@endThere are no instance variables introduced with a protocol.MAKIN’ COPIES
When you create a shallow copy, you don’t duplicate the referred objects; your new copy simply points at the referred objects that already exist. NSArray’s copy method makes shallow copies. When you make a copy of an NSArray, your copy only duplicates the pointers to the referred objects, not the objects themselves. If you copy an NSArray that holds five NSStrings, you still end up with five strings running around your program, not ten. In that case, each object ends up with a pointer to each string.
A deep copy, on the other hand, makes duplicates of all the referred objects. If NSArray’s copy was a deep copy, you’d have ten strings floating around after the copy was made.
Copy Protocol
To be able to make a copy of an engine, the class needs to adopt the NSCopying protocol.
@interface Engine : NSObject <NSCopying>
@end // EngineBecause we’ve adopted the NSCopying protocol, we have to implement the copyWithZone: method. A zone is anNSZone, which is a region of memory from which you can allocate memory.
Copy object that has no instance variable:
- (id) copyWithZone: (NSZone *) zone
{
Engine *engineCopy;
engineCopy = [[[self class] allocWithZone: zone] init];
return (engineCopy);
} // copyWithZone
Engine has no instance variables, so all we have to do is make a new engine object.
PS: If we use [Engine class], it only works for engine but not its subclass
Copy object that has instance variable:
@interface Tire : NSObject <NSCopying>
{
float pressure;
float treadDepth;
}
// ... methods
@end // Tire
- (id) copyWithZone: (NSZone *) zone
{
Tire *tireCopy;
tireCopy = [[[self class] allocWithZone: zone]
initWithPressure: pressure
treadDepth: treadDepth];
return (tireCopy);
} // copyWithZoneYou don’t have to use the designated initializer for copying. If you want, you can use a plain init and use accessor methods to change attributes.Copy subclass:
@interface AllWeatherRadial : Tire // protocol will be inherited
{
float rainHandling;
float snowHandling;
}
// ... methods
@end // AllWeatherRadial- (id) copyWithZone: (NSZone *) zone
{
AllWeatherRadial *tireCopy;
tireCopy = [super copyWithZone: zone];
[tireCopy setRainHandling: rainHandling];
[tireCopy setSnowHandling: snowHandling];
return (tireCopy);
} // copyWithZoneCopy class that contains other objects:
// suppose car only contains engine
- (id) copyWithZone: (NSZone *) zone
{
Car *carCopy;
carCopy = [[[self class]
allocWithZone: zone]
init];
carCopy.name = self.name;
Engine *engineCopy;
engineCopy = [[engine copy] autorelease]; // we need to autorelease copy,alloc,new!
carCopy.engine = engineCopy;
}
Protocols and Data Types
You can specify protocol names in the data types you use for instance variables and method arguments. By doing this, you give the Objective-C compiler a little more information so it can help error-check your code.
- (void) setObjectValue: (id<NSCopying>) obj;
Objective-C 2.0 adds two new modifiers for protocols: @optional and @required.
本文详细介绍了Objective-C中的NSCopying协议,包括如何声明、实现以及应用到不同类型的对象中,如简单对象、带有实例变量的对象、子类以及包含其他对象的对象。同时解释了浅拷贝和深拷贝的概念,并提供了具体的代码示例。

被折叠的 条评论
为什么被折叠?



