NSCopying & Inheritance - PullRequest
       0

NSCopying & Inheritance

5 голосов
/ 06 августа 2010

Пожалуйста, посмотрите на следующий код: ------- .h

@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 ]

30 голосов
/ 26 мая 2011

Ваш базовый 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: для копирования данных.

1 голос
/ 07 августа 2010

Хорошо, во-первых, ваш тестовый код неверен, потому что вы установили число сохранения 2001 в 8-битном целом числе.Во-вторых, ваш код не запускается, потому что вы пытаетесь вызвать setSavingNumber: andOffer: для BankAccount вместо объекта Saving, поэтому он не может найти селектор для этого метода во время выполнения.Спасибо Дэвиду за указание на это.

При реализации BankAccount :: copyWithZone вы использовали alloc-init и вернули объект, что нормально.При реализации Savings :: copyWithZone вы вызываете super copyWithZone.То, что вы получите, это объект типа BankAccount, поэтому вы не можете использовать setSavingNumber: andOffer: on.Поскольку вы использовали alloc-init в базовом классе, вы должны также использовать alloc-init и setMethods в классе Savings.

Чтобы избежать дублирования кода, я бы рекомендовал реализовать initWithBankAccount в BankAccount и то же самоев Savings.

Тогда в copyWithZone у вас будет

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

и

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

Хотя вы должны убедиться, что в initWithSavings вы вызываете либо

self = [super initWithBankAccount:savings];

или вы вызываете прямой init и копируете инициализацию базового элемента.

Посмотрите на Реализация копирования объекта из Руководства по программированию для управления памятью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...