Свойства делают много вещей. На самом поверхностном уровне они позволяют вам получить доступ к переменным-членам в точечной форме. В лучшем случае они могут быть отличными инструментами управления памятью (и не только).
Допустим, у вас есть переменная:
NSNumber * myNumber;
Позже в коде вы получаете доступ к нему как:
myNumber = [NSNumber numberWithInt: 5];
Проблема в том, что вы можете потерять ссылку на ранее сохраненное значение в myNumber. Возможная утечка памяти !! На данный момент у вас нет сохранения myNumber, и он может быть освобожден до того, как вы его используете.
Как могут помочь свойства? Допустим, вы определили свойство вокруг него и использовали синтез:
В определении интерфейса:
NSNumber * myNumber;
...
@property (retain, nonatomic) NSNumber * myNumber;
и
В файле реализации:
@synthesize myNumber;
Это создаст геттер и сеттер. Значение ... каждый раз, когда вы присваиваете myNumber чему-то, как в:
self.myNumber = newNumber;
вызывается следующий метод установки (созданный директивой synthesize):
- (NSNumber *) setMyNumber: (NSNumber *) newNumber {
[myNumber release];
myNumber = newNumber;
[myNumber retain];
return newNumber;
}
Здесь myNumber автоматически получает удержание. Это очень утомительно делать каждый раз вручную ... как вы можете видеть, гораздо проще использовать свойства.
Это все еще не идеальное решение! Зачем? Что если вы используете в своей реализации следующее утверждение:
myNumber = newNumber;
Помните, что свойства getter и setter вызываются только в том случае, если вы используете пунктирную запись (self.myNumber
). Итак, использование свойств для нас ничего не дало, потому что мы забыли их использовать!
Это очень распространенное явление, которое, скорее всего, упущено и вызывает разочарование.
Итак, как лучше? Это то, что я рекомендую (как и многие другие):
В классе интерфейса:
NSNumber * _myNumber;
...
@property (retain, nonatomic) NSNumber * myNumber;
В файле реализации:
@synthesize myNumber = _myNumber;
Теперь вы можете получить доступ к своему номеру как:
self.myNumber = whateverNewNumber;
Но если вы сделали:
myNumber = whateverNewNumber;
Вы получите ошибку ... потому что переменная myNumber просто не существует ... вынуждает вас использовать self.myNumber
каждый раз!
Кроме того, если вы решите пойти по этому пути, не забудьте о сделке:
- (void) dealloc {
[_myNumber release];
_myNumber = nil;
}
или более кратко:
- (void) dealloc {
self.myNumber = nil;
}