Правильно переопределить сеттер в Objective-C

17

Я просто попытался переопределить стандартные синтезированные сеттеры свойства. Пока все в порядке, я просто установил ivar на свое новое значение. Но потом я спросил себя: «Что происходит с сохранением количества сохраненных свойств» ... Я не нашел хорошего ответа, который объяснил это мне. Поэтому я прошу об этом здесь. Есть ли что-нибудь, о чем я должен знать, если я переопределяю установщик свойств, который установлен в retain , и как я могу сделать это правильно? Я не использую ARC.

Вот пример:

@property(nonatomic)NSInteger number;

- (void)setNumber:(NSInteger)number {
    _number = number;  // This should be fine, since it's no retained object I want to set
}


@property(nonatomic, retain)NSObject *something;

- (void)setSomething:(NSObject *)something {
    _something = something;  // This is not fine. As far as I know you should never do sth. like this... But how do I set it correctly?
}
    
задан E. Lüders 11.09.2012 в 14:31
источник

4 ответа

28
-(void) setAnObject:(NSObject*) someObject {
    if (_anObject != someObject) {
       NSObject* savedObject = _anObject;
       _anObject = [someObject retain];
       [savedObject release];
    }
}

Если вы отпустите старый указатель перед сохранением нового, вы можете иметь ситуацию, когда вы устанавливаете значение из значения в старом объекте, а выпуск старого объекта заставляет новый объект идти POOF! незадолго до его сохранения.

В качестве альтернативы вы можете сделать

....
[someObject retain];
[_anObject release];
_anObject = someObject;
...
    
ответ дан Hot Licks 11.09.2012 в 14:46
источник
5

Отредактировано после изучения принятого ответа от Hot Licks

объявление свойства и синтез x

@property (nonatomic, retain) ClassX x;
@synthesize x = _x;

перегруженный сеттер для x

- (void)setX:(ClassX *)x;
{
  if (x != _x)
  {
    [x retain];
    [_x release];
    _x = x;
    // custom code here
  }
}
    
ответ дан Damo 11.09.2012 в 14:39
источник
5

Вы переписываете сеттеры только для другого имени? Если это так, вы можете сделать это, изменив определение свойства:

@property(nonatomic, setter = nameOfSetter: )NSInteger number;

То же самое работает для getter.

    
ответ дан Thomas Johannesmeyer 11.09.2012 в 14:38
источник
4
- (void) setSomething:(NSObject*) something
{
    if (something != _something)
    {
        [_something release];
        _something = [something retain];
    }
}

Вам нужен оператор if , потому что в противном случае, если что-то и _something были уже одинаковы, вы бы перевыполнили объект, возможно, он исчезнет и возникли проблемы.

    
ответ дан Amy Worrall 11.09.2012 в 14:39
источник