Не удается получить доступ к членам подкласса после отправки в качестве суперкласса - PullRequest
0 голосов
/ 04 февраля 2011

Я не могу получить доступ к переменным-членам подкласса после отправки объекта как суперкласса. Функции-члены работают. Смотрите этот пример:

определение суперкласса

@interface SuperClass : NSObject {
 NSString *stringSuper;
 NSInteger intSuper;
}
- (void)test; // NSLog(@"test: SuperClass");

определение производного класса

@interface DerivedClass : SuperClass {
 NSString *stringDerived;
 NSInteger intDerived;
}
- (void)test; // NSLog(@"test: DerivedClass");
- (void)test1; // NSLog(@"test1: DerivedClass");

создать объект DerivedClass и отправить как SuperClass

DerivedClass *d = [[DerivedClass alloc] init];
d.stringSuper = anotherString;
d.intSuper = anotherInt;
d.stringDerived = anotherString1;
d.intDerived = anotherInt1;

[anObject sendMessage:d];

попытаться получить доступ к членам после приведения к DerivedClass

- (void)sendMessage:(SuperClass *)s {
 DerivedClass *d = (DerivedClass *)s;
 NSLog(@"%@", d.stringSuper); // ok
 NSLog(@"%d", d.intSuper); // ok
 NSLog(@"%@", d.stringDerived); // EXC_BAD_ACCESS
 NSLog(@"%d", d.intDerived); // ok

 [d test]; // ok ("test DerivedClass")
 [d test1]; // ok ("test1 DerivedClass")
}

Я объявил @properties (nonatomic, assign) для всех членов. Отладчик показывает мне правильный адрес для stringDerived, но он «выходит за рамки».

Кто-нибудь знает, в чем причина такого поведения?

Спасибо, Родо

1 Ответ

1 голос
/ 04 февраля 2011

Да: вы нарушили правило 1 как сделать свойства .Ясно, что anotherString1 был выпущен до точки, которую вы прочитали из d.stringDerived;возможно, он даже был недействительным в точке, которую вы установили d.stringDerived.Точно так же anotherString, очевидно, является либо постоянной строкой, либо сохраняется чем-то другим.Это было бы более очевидно, если бы вы показали свой фактический код.

Если вы определяете класс со свойством типа объекта, вы должны организовать экземпляры вашего класса для копирования или сохранения значения, назначенного этому свойству вЧтобы быть уверенным, что он все еще будет там, когда вы в следующий раз посмотрите.Если вы используете метод assign, это значение, вероятно, очень быстро станет недействительным, поскольку, скорее всего, оно будет автоматически освобождено.В общем, если тип свойства соответствует протоколу NSCopying и является изменяемым или имеет изменяемый подкласс (например, NSString, NSData, NSSet, NSArray и т. Д.), Лучше всего использовать copy, чтобы значение не изменилось ни разузадавать;в других случаях хорошо использовать retain.

Сделав это, вы также должны убедиться, что память, используемая значением свойства, правильно учтена при освобождении объекта.Установите значение любых свойств типа объекта равным nil в вашей подпрограмме dealloc.

...