歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Objective-C的NSCopying協議

Objective-C的NSCopying協議

日期:2017/3/1 9:40:28   编辑:Linux編程

在Objective-c中, 某個類遵守了NSCopying協議就代表這個類支持[obj copy]操作。在沒有實現NSCopying協議的情況下調用對象的copy函數則會出現異常。NSCopying協議只有一個函數,即copyWithZone, 聲明如下 :

@protocol NSCopying

- (id)copyWithZone:(NSZone *)zone;

@end

zone參數是新對象將分配到的內存區,一般不用修改。

遵守NSCopying協議則需要在@implementation中實現copyWithZone函數。

// Person
@interface Person : NSObject <NSCopying>

@property (nonatomic, copy) NSString* name;
@property int age ;

-(id) initWithName:(NSString*) pName andAge:(int) iAge ;
@end

Person類的實現。

// impl
@implementation Person

@synthesize name, age ;

//
-(id) initWithName:(NSString*) pName andAge:(int) iAge
{
self = [super init] ;
if ( self ) {
self.name = pName ;
self.age = iAge ;
}
return self ;
}

// 實現copyWithZone
-(id) copyWithZone:(NSZone *)zone
{
NSLog(@"Person copyWithZone, class : %@.", [self.class description]) ;
// 如果子類覆寫該方法, 則[self class]的類型為子類型,如果直接使用
// [[Person allocWithZone:zone] init], 則子類覆寫時會出錯.
Person* per = [[[self class] allocWithZone:zone] init] ;
per.name = self.name ;
per.age = self.age ;
return per ;
}

@end

// impl
@implementation Person

@synthesize name, age ;

//
-(id) initWithName:(NSString*) pName andAge:(int) iAge
{
self = [super init] ;
if ( self ) {
self.name = pName ;
self.age = iAge ;
}
return self ;
}

// 實現copyWithZone
-(id) copyWithZone:(NSZone *)zone
{
NSLog(@"Person copyWithZone, class : %@.", [self.class description]) ;
// 如果子類覆寫該方法, 則[self class]的類型為子類型,如果直接使用
// [[Person allocWithZone:zone] init], 則子類覆寫時會出錯.
Person* per = [[[self class] allocWithZone:zone] init] ;
per.name = self.name ;
per.age = self.age ;
return per ;
}

@end

在copyWithZone函數中創建了一個對象,並且將屬性挨個拷貝給新的對象。注意新對象per的創建方法

[[[self class] allocWithZone:zone] init] ;

而不是

[[Person allocWithZone:zone] init] ;

這是因為如果有子類覆寫了copyWithZone函數,那麼在子類對象被拷貝時會調用Person類的copyWithZone函數, 如果硬編碼類型為Person, 則創建的對象為Person類型, 而不是子類型,因此會出現異常。而[self class]則會獲取正確的類型, 並且創建出正確的對象,避免異常出現。

例如Student類繼承自Person類。

// subclass, Student
@interface Student : Person
// 班級名
@property (nonatomic, copy) NSString* className ;

@end

// subclass, Student
@interface Student : Person
// 班級名
@property (nonatomic, copy) NSString* className ;

@end

Student的實現,覆寫copyWithZone函數。

// Student實現
@implementation Student

// 覆寫copyWithZone,
-(id) copyWithZone:(NSZone *)zone
{
// 1、先調用父類的copyWithZone函數
Student* per = [super copyWithZone:zone] ;
// 2、再設置className
per.className = self.className ;
NSLog(@"Student copyWithZone") ;
return per ;
}

@end

Objective-C中@property的所有屬性詳解 http://www.linuxidc.com/Linux/2014-03/97744.htm

Objective-C 和 Core Foundation 對象相互轉換的內存管理總結 http://www.linuxidc.com/Linux/2014-03/97626.htm

使用 Objective-C 一年後我對它的看法 http://www.linuxidc.com/Linux/2013-12/94309.htm

10個Objective-C基礎面試題,iOS面試必備 http://www.linuxidc.com/Linux/2013-07/87393.htm

Objective-C適用C數學函數 <math.h> http://www.linuxidc.com/Linux/2013-06/86215.htm

Copyright © Linux教程網 All Rights Reserved