2010-08-06 15 views
5

si prega di dare uno sguardo sul seguente codice: ------- .hNSCopying & Inheritance

@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 

Quando eseguire questo codice ::::::

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]; 
#

io non so cosa è sbagliato con il codice per favore mi aiuti. Grazie in anticipo.

Grazie Deepak

+2

Si prega di formattare il codice e fare una domanda. Qual è il comportamento attuale, quale sarebbe il previsto. –

risposta

1

Ok prima, il tuo codice di prova è un male perché si imposta un numero risparmio del 2001 in un numero intero a 8 bit. In secondo luogo, il tuo codice non viene eseguito perché stai cercando di chiamare setSavingNumber: andOffer: su un BankAccount invece che su un oggetto di salvataggio in modo che non possa trovare il selettore per questo metodo in fase di esecuzione. Grazie a David per averlo indicato.

Quando si implementa BankAccount :: copyWithZone, si è utilizzato l'alloc-init e l'oggetto restituito è corretto. Quando si implementa Savings :: copyWithZone, si chiama super copyWithZone. Quello che ottieni è un oggetto di tipo BankAccount quindi non puoi usare setSavingNumber: andOffer: su di esso. Dato che hai usato alloc-init nella classe base, dovresti usare anche alloc-init e setMethods nella classe Savings.

Per evitare la duplicazione del codice, consiglierei di implementare un initWithBankAccount in BankAccount e lo stesso in Risparmio.

Poi nel copyWithZone, avresti

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

e

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

Anche se è necessario fare in modo che in initWithSavings si chiama sia

self = [super initWithBankAccount:savings]; 

o si chiama dritto init e si copia l'inizializzazione del membro di base.

Dai un'occhiata a Implementing object copy dalla guida alla programmazione della gestione della memoria.

+0

Diversamente da C++ o C, la natura dinamica dell'obiettivo-c consentirà di gestire i messaggi non gestiti su un oggetto, ma non funzionerà in fase di esecuzione (al contrario della compilazione, come si menziona). Si prega di aggiornare la risposta per riflettere questo. – David

+0

Il problema con la chiamata 'initWithBankAccount:' in 'BankWaveZone' di BankAccount' è che non restituirà quei membri come copie profonde. Questo può o non può dare problemi per te in seguito. – Marius

+0

Ovviamente questo va bene se tutti i membri sono riferimenti deboli e non sono necessarie copie. Ad esempio, se si desidera utilizzare una classe come chiave in un 'NSDictionary' o usarla in' NSSet', modificare i valori su cui si basa l'ordine può dare problemi/errori. – Marius

28

Il tuo metodo di base copyWithZone: dovrebbe assomigliare a questa:

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

    // copy base members: 
    // ... 

    return base; 
} 

I suoi derivati ​​copyWithZone: metodi dovrebbe essere simile a questo:

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

    // copy derived members: 
    // ... 

    return derived; 
} 

Assicurarsi inoltre che si stanno facendo copie profonde di riferimenti forti e poco profondo copie di riferimenti deboli. Così per i membri esempio copia di tipo NSString e NSArray (ciascuno con i membri fortemente riferimento e uno con debole) fare:

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; 

(. Abitualmente membri deboli vengono assegnati/conservati e variabili forti vengono copiati)

Prendere nota che per questo motivo non è necessario utilizzare i metodi di tipo initWithMyself: per copiare i dati.

+0

copyWithZone non restituisce necessariamente una copia profonda. Dai un'occhiata al modello Prototype. Utilizza il protocollo NSCopying in combinazione con NSArchiver e NSUnarchiver per semplificare la copiatura di un compito facile. –

+2

+1 per '[auto classe]' nella classe base allocWithZone. Condannato senza quello! – Echelon

+1

In molte domande StackOverflow viene spiegato NSCopying, ma in qualche modo mancano di evidenziare l'uso di [self class]. –