2010-08-06 38 views
5

请对下面的代码来看看:------- .HNSCopying和继承

@interface BankAccount : NSObject<NSCopying> 
{ 
    double accountBalance; 
    long accountNumber; 
    NSString *CustomerName; 
    NSString *AccountType; 
} 

-(void) setAccount: (long) y andBalance: (double) x; 
-(void) setCustomerName: (NSString*) name andAccountType: (NSString*) type; 
-(id)copyWithZone:(NSZone *)zone; 

@end 

@interface Savings : BankAccount 
{ 
    int number; 
    NSString *Offer; 
} 
-(void) setSavingNumber: (uint8_t) num andOffer: (NSString*) offer; 
-(id)copyWithZone:(NSZone *)zone; 
@end 

---------- .M

@implementation BankAccount 

-(void) setAccount: (long) y andBalance: (double) x 
{ 
    accountNumber = y; 
    accountBalance = x; 
} 
-(void) setCustomerName: (NSString*) name andAccountType: (NSString*) type 
{ 
    CustomerName = name; 
    AccountType = type; 
} 

-(id)copyWithZone:(NSZone *)zone 
{ 
    BankAccount *accountCopy = [[BankAccount allocWithZone: zone] init]; 
    [accountCopy setAccount: accountNumber andBalance: accountBalance]; 
    [accountCopy setCustomerName:CustomerName andAccountType:AccountType]; 
    return accountCopy; 
} 

@end 

@implementation Savings 
-(void) setSavingNumber: (uint8_t) num andOffer: (NSString*) offer 
{ 
    number = num; 
    Offer = offer; 
} 

-(id)copyWithZone:(NSZone *)zone 
{ 
    Savings * clone = [super copyWithZone:zone]; 
    [clone setSavingNumber:number andOffer:Offer];************** error ********* 
    return clone; 
} 

@end 

当运行此代码::::::

Savings* account1; 
Savings* account2; 

account1 = [[Savings alloc] init]; 
[account1 setAccount:10 andBalance:1000.10]; 
[account1 setCustomerName:[NSString stringWithFormat:@"%@",@"Deepak"] andAccountType:[NSString stringWithFormat:@"%@",@"Savings"]]; 
[account1 setSavingNumber:2001 andOffer:@"Bad"];  
account2 = [account1 copy]; 

我不知道什么是错的代码,请帮助我。提前致谢。

感谢 迪帕克

+2

请格式化代码并提出问题。目前的行为是什么,预期会是什么。 – 2010-08-06 12:30:27

回答

1

好吧第一,你的测试代码是不好的,因为你在一个8位整数设定的2001年一保存号。其次,代码不会运行,因为您试图在BankAccount而不是Save对象上调用setSavingNumber:andOffer:因此它在运行时无法找到此方法的选择器。感谢大卫指出了这一点。

当实现BankAccount :: copyWithZone时,你使用了alloc-init,并且你返回了很好的对象。在实施Savings :: copyWithZone时,您可以调用super copyWithZone。你得到的是一个BankAccount类型的对象,所以你不能使用setSavingNumber:andOffer:就可以了。由于您在基类中使用了alloc-init,因此您还应该在Savings类中使用alloc-init和setMethods。

为了避免重复代码,我会推荐在BankAccount中实现一个initWithBankAccount并且在Savings中也是一样。

然后在copyWithZone,你必须

return [[BankAccount allocWithZone:zone] initWithBankAccount:self]; 

return [[Savings allocWithZone:zone] initWithSavings:self]; 

虽然你必须确保在initWithSavings你打电话或者

self = [super initWithBankAccount:savings]; 

还是你打直init并复制基本成员初始化。

查看Memory management programming guide的Implementing object copy

+0

与C++或C不同,objective-c的动态特性将允许未处理的消息传递给对象,但在运行时会失败(与您提到的编译相反)。请更新答案以反映这一点。 – David 2010-08-09 14:27:39

+0

在BankAccount的'copyWithZone'中调用'initWithBankAccount:'的问题是它不会将这些成员作为深度副本返回。这可能会也可能不会给你以后的问题。 – Marius 2011-05-26 18:12:15

+0

当然这很好,如果所有的成员碰巧是弱引用,并且不需要副本。但是请注意,如果您希望在“NSDictionary”中使用类作为键或在“NSSet”中使用它们,则更改排序依赖的值可能会导致问题/错误。 – Marius 2011-05-26 19:49:08

28

你的基地copyWithZone:方法应该是这样的:

-(id)copyWithZone:(NSZone *)zone { 
    // change this line to use [self class] 
    BaseClass *base = [[[self class] allocWithZone:zone] init]; 

    // copy base members: 
    // ... 

    return base; 
} 

派生的copyWithZone:方法应该是这样的:

-(id)copyWithZone:(NSZone *)zone { 
    DerivedClass *derived = [super copyWithZone:zone]; 

    // copy derived members: 
    // ... 

    return derived; 
} 

还要确保确保你正在强引用浅浅的深层副本弱引用的副本。因此,为了对NSString类型和NSArray(每一个与强烈引用部件和一个具有弱)的例子拷贝成员做:

derived.strongString = [[strongString copyWithZone:zone] autorelease]; 
derived.weakString  = weakString; 
derived.strArrWStrVals = [[strArrWStrVals copyWithZone:zone] autorelease]; 
derived.strArrWWeakVals = [[[NSArray allocWithZone:zone] 
          initWithArray:strArrWWeakVals] autorelease]; 
derived.weakArray  = weakArray; 

(一般弱成员也被分配/保留和强变量被复制)

请注意,因此,您不应使用initWithMyself:类型的方法来复制数据。

+0

copyWithZone不一定会返回深层副本。看看原型模式。它将NSCopying协议与NSArchiver和NSUnarchiver结合使用,使复制成为一项简单的任务。 – 2012-03-19 12:40:13

+2

对于基类allocWithZone中的'[self class]'+1。没有这个注定! – Echelon 2014-10-24 17:16:31

+1

在许多stackoverflow问题NSCopying解释,但不知何故,他们错过了突出使用[自我班]。 – 2016-09-30 08:34:23