Расстраивающая картина в Цели С
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 приведет к сбою вашего кода.