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

18

Я просто попытался переопределить стандартные синтезированные сеттеры свойства. Пока все в порядке, я просто установил 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
источник
  • Из использования сохранения я понимаю, что вы не используете ARC? –  waldrumpus 11.09.2012 в 14:34
  • Да, я не использую дугу –  E. Lüders 11.09.2012 в 14:35
  • вам просто нужно установить счетчик удержания самостоятельно - вот и все –  MrBr 11.09.2012 в 14:43

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
  • +1 за то, что вы правы! –  Damo 12.09.2012 в 01:26
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
  • Thx, именно то, что я искал! –  E. Lüders 11.09.2012 в 14:44
  • Но представьте, если вы делаете self.x = [self.x objectAtIndex: 0] ;. –  Hot Licks 11.09.2012 в 14:47
  • self.x = [self.x objectAtIndex: 0]; просто возится с моей головой :-) –  Damo 11.09.2012 в 15:10
  • Проблема (для тех, кто еще не получил ее, заключается в том, что результат objectAtIndex сохраняется только текущим объектом (предположительно NSArray) в x. Если setX освобождает текущий объект и только затем сохраняет новый значение, NSArray и все объекты в нем будут выпущены, что означает, что значение, которое будет установлено в x, будет выпущено. Это может привести к некоторым довольно неясным и неприятным ошибкам. –  Hot Licks 11.09.2012 в 18:11
5

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

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

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

    
ответ дан Thomas Johannesmeyer 11.09.2012 в 14:38
  • Я знаю это, но спасибо. Нет, я не хочу давать им просто другое имя. Я хочу добавить настраиваемый код в сеттер. –  E. Lüders 11.09.2012 в 14:40
4
- (void) setSomething:(NSObject*) something
{
    if (something != _something)
    {
        [_something release];
        _something = [something retain];
    }
}

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

    
ответ дан Amy Worrall 11.09.2012 в 14:39
  • Ну, но NSInteger не является объектом. –  Hot Licks 11.09.2012 в 14:40
  • D'oh! Скопировал неправильный пример. Будет редактировать. –  Amy Worrall 11.09.2012 в 14:41
  • Все еще не удается для self.something = [self.something objectAtIndex: 0]; –  Hot Licks 15.03.2013 в 01:37