您的位置:首页 > 职场人生

黑马程序员_OC中对象的复制

2014-04-01 12:26 295 查看
----------------------
ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------

关于对象的浅复制与深复制

浅复制(shallow copy):不会复制所引用的对象,新复制的对象只会指向现有的引用对象。当复制一个NSArray类的对象时,复制的对象只会复制指向引用对象的指针,而不会复制引用对象本身。如果复制了一个包含5个NSString对象的NSArray对象,你最终得到的时5个可供程序使用的字符串对象,而不是10个。

深复制(deep copy):将复制所有的引用对象。如果NSArray的copy方法是深层复制,则在操作完成后得到10个字符串对象。

创建对象的副本

假设我们有一个Engine类。为了能够复制engine对象,Engine类需要采用NSCopying协议。下面是Engine类的新接口:

@interface Engine: NSObject <NSCopying>
@end


因为Engine类采用了NSCopying协议,所以我们必须实现copyWithZone:方法(关于NSCopying协议,上一篇博文已做了简单介绍)。zone是NSZ one类的一个对象,指向一块可供分配的内存区域。当你向一个对象发送copy消息时,该copy消息在到达你的代码前会被转换为copyWithZone:方法。

Engine类的copyWithZone:方法的实现如下:

@implementation Engine:

- (id) copyWithZone: (NSZone *)zone
{
Engine *engineCopy;
engineCopy = [[[self class] allocWithZone: zone] init];
return engineCopy;
} // copyWithZone


由于Engine类没有实例变量,因此我们必须创建一个新的engine对象。copyWithZone:方法的首要任务是获得self参数所属得类,然后向self对象所属得类发送copyWithZone:消息,以分配内存并创建一个该类得新对象。最后,copyWithZone:方法给这个新对象发送allocWithZone:消息使其初始化。

由于allocWithZone:方法是一个类方法。我们需要发消息给一个类。在这里是Engine类。为什么不像下面这样写:

[Engine allocWithZone: zone];


因为,这行代码只适用于Engine类。如果我们创建了Engine类的子类。这就会变的的不适用了。所以我们应该通过[self class]获得当前这个类。

这个实例的完整代码如下:

Engine.h

#import <Cocoa/Cocoa.h>

@interface Engine : NSObject <NSCopying>
@end // Engine


Engine.m

#import "Engine.h"

@implementation Engine

- (id) copyWithZone: (NSZone *) zone
{
Engine *engineCopy;
engineCopy = [[[self class] allocWithZone: zone] init];

return (engineCopy);

} // copyWithZone

- (NSString *) description
{
return (@"I am an engine.  Vrooom!");
} // description

@end // Engine


main.m

#import <Foundation/Foundation.h>
#import "Engine.h"

int main(int argc, const char * argv[])
{

@autoreleasepool {
Engine *engine = [[Engine alloc] init];
NSLog(@"%@", engine);

Engine *engineCopy = [engine copy];
NSLog(@"%@", engineCopy);

}
return 0;
}


运行后,结果如下:



----------------------
ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: