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

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

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

Вот пример:

@property(nonatomic)NSInteger number;

- (void)setNumber:(NSInteger)number {
    _number = number;  // This should be fine, since it 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?
}
4b9b3361

Ответ 1

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

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

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

....
[someObject retain];
[_anObject release];
_anObject = someObject;
...

Ответ 2

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

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

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

Ответ 3

Отредактировано после изучения принятого ответа от 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
  }
}

Ответ 4

- (void) setSomething:(NSObject*) something
{
    if (something != _something)
    {
        [_something release];
        _something = [something retain];
    }
}

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