Вы всегда должны использовать средства доступа к свойствам (что в Objective-C 2.0 означает использование обозначения self.property
.)
Почему? Потому что он обеспечивает автоматический контроль доступа и управление жизненным циклом объекта. Сгенерированные средства доступа могут обеспечить большую защиту, такую как чтение / запись, копирование, сохранение и т. Д., Которые в противном случае требуют большого количества ручного кода. Если вы пишете свои собственные методы доступа, вы можете добавить все необходимые валидации и побочные эффекты.
(Еще до того, как аксессоры Objective-C 2.0 считались высоким искусством. Это все еще возможно, если вы полностью используете потенциал.)
Единственный раз, когда вы должны обращаться к свойствам напрямую, это когда вы пишете метод доступа. Например, возьмите этот общий шаблон:
@property(nonatomic, retain) NSMutableArray *myObjects;
@synthesize myObjects;
-(NSMutableArray *) myObjects{
if (myObect!=nil) {
return myObect;
}
NSMutableArray *anArray=[[NSMutableArray alloc] initWithCapacity:1];
self.myObject=anArray;
[anArray release]
return myObject;
}
- Этот метод доступа гарантирует, что myObjects никогда не будет равен нулю, что устраняет большую часть стандартного тестирования нуля в остальной части вашего кода.
- Вы, очевидно, не можете вызвать
self.myObjects
(который на самом деле является [self myObjects]) внутри средства доступа без создания бесконечной рекурсии, поэтому вы должны получить доступ к необработанной переменной здесь, но ...
- ... Вы можете вызвать (автоматически сгенерированный)
self.myObjects=
(который на самом деле [self setMyObjects: anArray]), потому что это совершенно другой метод. Если вы посмотрите на внутренние элементы setMyObjects: вы увидите, что он также обращается к необработанной переменной.
- Если вы используете сгенерированные средства доступа,
self.myObjects=
обрабатывает сохранение, копирование, обнуление и т. Д. Каждый раз, когда вы вызываете его. Единственный раз, когда вам нужно позвонить релиз, находится в dealloc. Это само по себе стирает, вероятно, половину ошибок, которые делают люди в Objective-C.
И наоборот, вне метода доступа вы абсолютно ничего не получаете, напрямую обращаясь к свойствам внутри собственных методов классов. Все, что он делает, это сохраняет некоторые нажатия клавиш, подвергая вас риску трудно найти ошибки.
Как показали предыдущие ответы, вы допустили несколько ошибок памяти, пытаясь управлять свойством напрямую. Если бы вы использовали аксессор каждый раз, вы бы их не сделали. Например:
pickerData = [[[NSArray alloc] initWithObjects:@"A", @"B", @"C", nil] retain];
... каждый раз нужно правильно управлять, тогда как ...
self.pickerData = [[NSArray alloc] initWithObjects:@"A", @"B", @"C", nil];
... автоматически корректно.
Помните, что конечная цель разработки для любого класса Objective-C состоит в том, что он должен быть идеально модульным и многоразовым. Это означает, что он должен управлять всей своей собственной памятью, собственной проверкой данных и собственными побочными эффектами. Средства доступа абсолютно необходимы для этого управления. Оборачивая логику вокруг каждого доступа к переменной, вы гарантируете, что (1) это ожидаемый вами тип, диапазон и т. Д. И (2) что он всегда рядом, когда вам это необходимо (3) что вы можете контролировать все стороны последствия записи или чтения переменной и (4) ее отсутствие.
Я не могу достаточно превозносить достоинства аксессоров. На самом деле, я мог бы написать небольшую песню. ; -)