Расстраивающая картина в Цели С

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

- (id) init
{
    self = [super init];

    if (self)
    {
           [self someMethod];
    }

    return self;

}

- (void) someMethod
{
    _x = 0; \\ or self.x = 0 when this method is not called from initializer
}

someMethod содержит кучу иваров в нем. Проблема в том, что его также нужно вызывать в другом месте, где в коде позже после инициализации объекта. Я хотел бы, чтобы средства доступа не были доступны в инициализаторе, когда он вызывается оттуда, но я также хотел бы, чтобы к ним обращались, когда someMethod называется откуда-то еще. Есть ли аккуратный способ обойти этот паттерн? Когда используешь NSObject? Когда используешь UIView? Когда используешь UIViewController?

1 ответ

Решение

Чтобы судить, безопасно ли игнорировать рекомендацию, вы должны понять, почему эта рекомендация существует.
Основная проблема - это методы получения и установки, которые имеют побочные эффекты, поскольку они выполняют вычисления на основе переменных экземпляра, которые могут не инициализироваться при вызове метода установки (или метода получения).

Возьмите следующий код в качестве примера:

- (id)init {
    self = [super init];
    if (self) {
        // don't do this
        self.textColor = [UIColor blackColor];
        self.font = [UIFont boldSystemFontOfSize:17];

        // do this:
        _textColor = [UIColor blackColor];
        _font = [UIFont boldSystemFontOfSize:17];
        [self createLayers];
    }
    return self;
}

- (void)setFont:(UIFont *)font {
    if (font) {
        _font = font;
        [self createLayers];
    }
}

- (void)setTextColor:(UIColor *)textColor {
    if (textColor) {
        _textColor = textColor;
        [self createLayers];
    }
}

- (void)createLayers {
    // calculation that will crash if font or textColor is not set
}

Поскольку createLayers падает, если textColor или font равен nil, использование метода установки в init приведет к сбою вашего кода.

Другие вопросы по тегам