Переопределить @property setter и бесконечный цикл
Существует класс A с:
@interface ClassA : NSObject {
}
@property (nonatomic, assign) id prop1;
@end
@implementation
@synthesize prop1;
@end
то у меня есть подкласс
@interface ClassB : ClassA {
}
@end
@implementation
- (id)init {
self = [super init];
if (self) {
}
return self;
}
//This is infinite loop
- (void) setProp1:(id)aProp
{
self.prop1 = aProp;
}
@end
и это бесконечный цикл, потому что setProp1 из ClassB вызывает [ClassB setProp1: val] из класса ClassB.
Я уже пробовал вызов [super setProp1], но этот
Как перезаписать @property и присвоить значение внутри перезаписываемого сеттера? И пусть предположим, что я не могу изменять ClassA.
Ответы
Ответ 1
Просто назначьте переменную экземпляра напрямую, не используя синтаксис точки, чтобы вызвать установщик:
- (void) setProp1:(id)aProp
{
self->prop1 = aProp;
}
Тем не менее этот вопрос задает вопрос. Весь этот аксессуар делает именно то, что сделал бы родительский, - так, какова точка переопределения родителя вообще?
Ответ 2
С XCode 4.5+ и LLVM 4.1 нет необходимости в @synthesize, вы получите ссылку _prop1.
- (void) setProp1:(id)aProp
{
_prop1 = aProp;
}
Будет работать нормально.
Ответ 3
Вы не должны использовать "self" внутри сеттера, так как это создает рекурсивный вызов.
Кроме того, вы должны проверить, чтобы убедиться, что вы не назначаете один и тот же объект, сохраните новый объект и отпустите старый объект перед назначением.
И вы должны переопределить имя сеттера, как было предложено выше:
@synthesize prop1 = prop1_;
...
- (void) setProp1:(id)aProp
{
if (prop1_ != aProp) {
[aProp retain];
[prop1_ release];
prop1_ = aProp;
}
}
Ответ 4
Другой альтернативой является установка синтезированной переменной на другое имя следующим образом:
@synthesize selectedQuestion = _selectedQuestion;
И затем обратитесь к нему как _selectedQuestion
. Это предотвращает случайную запись selectedQuestion, когда вы имели в виду self.selectedQuestion.
Однако Apple рекомендует не использовать знак подчеркивания. Вы можете использовать другое имя, но метод @Sherm является лучшим, imho.
Ответ 5
Просто @synthesize
требуемое свойство в вашем подклассе, вы можете использовать его как имя для прямого доступа к свойству:
Интерфейс основного класса:
@interface AClass : NSObject
@property (nonatomic, assign) id<someProtocol> delegate;
@end
Интерфейс подкласса:
@interface BCLass : AClass
@end
Реализация подкласса:
@implementation BCLass
@synthesize delegate = _delegate;
- (void)setDelegate:(id<someProtocol>)d{
_delegate = d;
}
@end