Допустимое использование средств доступа в методах init и dealloc?

StackOverflow https://stackoverflow.com/questions/1283419

Вопрос

Сейчас я услышал об этом из нескольких источников (stackoverflow.com , cocoa-dev, документация, блоги и т.д.), Что "неправильно" использовать средства доступа и настройки (foo, setFoo:) в ваших методах init и dealloc.Я понимаю, что существует отдаленная возможность запутать другие объекты, которые наблюдают за этим свойством, если вы это сделаете.(приведен простой пример здесь)

Однако я должен сказать, что я не согласен с такой практикой по следующей причине:

Новая среда выполнения Objective-C (та, что на iPhone, и 64-разрядная среда выполнения в версии 10.5) позволяет объявлять свойства без объявляя соответствующий ivar.Например, следующий класс будет просто отлично скомпилирован на версии 10.5 или для iPhone (устройства, а не симулятора).:

@interface Foo : NSObject { }

  @property (retain) id someObject;

@end

@implementation Foo

  @synthesize someObject;

@end

Понимая, что приведенное выше является вполне допустимым классом Objective-C, допустим, я решаю написать инициализатор, а для целей управления памятью - метод dealloc (поскольку GC недоступен на iPhone).Все, что я когда-либо читал об инициализаторах и освобождении, привело бы меня к написанию следующих двух методов:

- (id) init {
  if (self = [super init]) {
    //initialize the value of someObject to nil
    [self setSomeObject:nil];
  }
  return self;
}

- (void) dealloc {
  //setting someObject to nil will release the previous value
  [self setSomeObject:nil];
  [super dealloc];
}

Однако, согласно документации и распространенному мнению, это "неправильно".Итак, мои вопросы заключаются в следующем:

  1. Как я должен инициализировать SomeObject без использования средства доступа?Вы могли бы сказать, что компилятор (или среда выполнения, или что-то еще) гарантирует, что SomeObject уже имеет значение nil, но я считаю, что полагаться на это было бы неправильным поведением.Имея приличный опыт работы в C, я видел изрядное количество ошибок из-за неправильной инициализации переменных, и это, кажется, немного отличается.
  2. Как я могу освободить SomeObject, если я не должен использовать средство доступа в методе dealloc?

Если ответ на любой из этих вопросов "вы не можете", то как может быть плохо использовать средства доступа в ваших методах init и dealloc?

Это было полезно?

Решение

Я понимаю, что текущее поведение 10.5, при котором синтезированные ivars недоступны напрямую, рассматривается Apple как ошибка;вы должны иметь возможность получить к нему прямой доступ, но не можете.

Следовательно, вы должны быть в состоянии сделать:

someObject = nil;

вместо того , чтобы

self.someObject = nil;

В то же время, прямое использование средства доступа - единственный способ сделать это без предоставления явного ivar.

Обновить:Эта ошибка была исправлена;теперь вы можете сделать someObject = nil просто отлично.

Другие советы

РЕДАКТИРОВАТЬ (13 февраля 2013): Как отмечено в моем комментарии ниже, и особенно после добавления ARC, я изменил свое мнение по этому поводу.До ARC я видел много ошибок, приводящих к сбоям, из-за неправильных назначений ivar в init.IMO, особенно при работе с младшими командами, редкие проблемы с использованием средств доступа в init были перевешены распространенными ошибками ivar access.Поскольку ARC устранил такого рода ошибки, редкие, но возможные ошибки, которые при использовании accessor в init могут быть более важными, и поэтому я переключился на поддержку прямого использования ivars в init и dealloc, и только в тех местах;средства доступа везде, где это возможно (очевидно, вы не можете использовать средства доступа внутри самого средства доступа ....)


Ответ ПЕРЕД ДУГОЙ

Я категорически не согласен с теми, кто возражает против средств доступа в -init.Почти во всех случаях это очень хорошее место для использования средств доступа, и это избавляет от множества ошибок, которые я видел в новых кодерах Cocoa, которые неизменно не сохраняются при назначении в -init.

-dealloc это более жесткий вызов.У меня есть естественная склонность использовать там средства доступа (чтобы они использовались везде), но это может вызвать головную боль из-за KVO (или даже NSNotifications, если вы опубликуете уведомление об изменении в своем установщике).Тем не менее, хотя я не использую средства доступа в -dealloc, Я считаю это очень спорным, и Apple очень непоследовательна в этом вопросе (мы знаем, что они звонят setView: в UIViewController -dealloc например).

В любом случае, я бы сказал, что недостаточное использование средств доступа в 100 раз увеличило количество ошибок, связанных с чрезмерным использованием.Я бы всегда ошибался в их использовании, за исключением случаев, когда есть веская причина не делать этого.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top