簡體   English   中英

初始化對象的最佳方法是什么?

[英]What is the best way to initialize an object?

我已經使用Objective-C幾年了,但我仍然不確定如何初始化一個對象。 我們的問題是:

-(id)init {
    self = [super init];
    if (self) {
        self.backgroundColor = [UIColor blueColor];
        self.textColor = [UIColor greenColor];
    }
    return self;
}

-(id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor yellowColor];
    }
    return self;
}

在兩種方法中對它進行初始化都意味着復制和粘貼編碼(巨大的禁忌,由於人為錯誤導致無窮無盡的問題,例如值不同,如上例所示)或新方法:

-(id)init {
    self = [super init];
    if (self) {
        [self initialSetup];
    }
    return self;
}

-(id)initialSetup {
    self.backgroundColor = [UIColor blueColor];
    self.textColor = [UIColor greenColor];
}

這就產生了一個問題,即如果一個子類有一個initialSetup方法,那么調用[self initialSetup]的超類將調用子類的initialSetup ,從而忽略所有超類的設置。 您可以通過每次附加類名來解決此問題,例如initialSetupTextField

這看起來相當混亂。 這只是初始化一個對象。 別人怎么做到這一點?

每個班級都應該有一個指定的初始化者 ; 必須始終調用一個真正的init...方法變體來正確初始化類(如Matt所述)。

但是,這並沒有完全解決問題,因為類也可能通過unarchival支持實例化,這會在你的問題中遇到同樣的“我在哪里放置常見的初始化goop”問題。

通常,我創建一個方法,如:

- (void)commonInit
{
     ... common initialization goop goes here ...
}

然后從指定的初始值設定項和/或initWithCoder: 首先調用它initWithCoder:

是的,有點亂,但你可以做的不多。

減少混亂的一般策略:

•提供非常少的初始化器; 也許init +一個初始化程序,包含其他配置的所有可能參數。

•將super初始化程序指定為DI,並通過它調用任何其他初始化程序。 當子類化你有一個更具體的DI(參見UIViewinitWithFrame: [self initFancy:...] ,覆蓋超級的DI來調用[self initFancy:...]然后調用[super initThroughSupersDI]

您錯過了指定初始化程序的概念。 你編寫了一個執行繁重工作的init方法。 所有其他初始化程序只調用指定的初始化程序。 你的例子看起來像:

-(id)init {
    return [self initWithFrame:CGRectZero];
}

-(id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor yellowColor];
    }
    return self;
}

...每次附加類名,例如-initialSetupTextField

是的,確切地說,或者您可以為私有實例初始化例程創建一個C函數 - 當指定的初始化程序不足時。 我使用了與你不同的命名方案,但只要你使用避免碰撞的約定,那么你就是好的。 我提到這一點,因為你的例子中的方法可能會混淆吸氣劑。

我做的另一件事是從這個例程返回一個值,表示是否有錯誤(即應該返回nil )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM