歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Objective-C的NSCopying協議

在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