Подтвердить что ты не робот

Переопределить @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.

4b9b3361

Ответ 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