目标C中的令人沮丧的模式

时间:2013-03-18 07:23:39

标签: iphone ios cocoa-touch cocoa-design-patterns

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包含一堆ivars。问题是,在初始化对象之后,还需要在稍后的代码中调用else。我希望在从那里调用访问器时不能在初始化器中访问它们,但我也希望在从其他地方调用someMethod时访问它们。这个模式有一个巧妙的方法吗?使用NSObject时?使用UIView时?使用UIViewController

1 个答案:

答案 0 :(得分:4)

要判断忽略推荐是否安全,您必须了解为什么存在此建议 主要问题是具有副作用的getter和setter,因为它们基于实例变量执行计算,这些变量在调用setter(或getter)时可能无法初始化。

以下面的代码为例:

- (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
}

因为如果textColor或font为nil,createLayers会崩溃,在init中使用setter会导致代码崩溃。