2013-03-19 231 views
1

我一直在爲我的對象創建自定義初始化程序,僅僅因爲它感覺比以其他方式設置變量更好。在這些初始化程序中,我通常會設置對象的變量,然後將調用返回到主init。自定義對象初始化程序

因此,例如,在UIViewController子類我的代碼看起來是這樣的:

-(id)initWithValue:(int)val { 
    self.value = val; 
    return [self initWithNibName:nil bundle:nil]; 
} 

其中value是屬於該視圖控制器子類的整數,並且有比平常更多的價值。

但是,最近我開始設置自己的第一個,因爲我認爲self = [self init...]將取代當前類的實例,因此我會失去自己的實例。 所以,我開始做:

-(id)initWithValue:(int)val { 
    self = [self initWithNibName:nil bundle:nil]; 
    self.value = val; 
    return self; 
} 

然後我最近檢查的原始版本,並意識到,一切都沒有正常工作,該變化是不必要的。

所以,我的問題是這樣的:

  1. 什麼是[超級initWithNibName:束:]做的,這是造成它創建一個對象,但不會取代原來的對象?
  2. 是兩個版本之一比另一個更好使用還是它們都是等價的?如果一個更好,應該使用哪個?

謝謝先進!

回答

0

您寫的第一個代碼不會存儲value,因爲在創建對象之前,您正試圖存儲數據。 但是,第二個代碼,需要更好的做法,即,像這樣的小改...

-(id)initWithValue:(int)val { 
    self = [self initWithNibName:nil bundle:nil]; 

    if(self) 
    _value = val; 

    return self; 
} 

希望這是對你有用... :-)

+0

這就是我想,但我嘗試設置值,然後做'自我=可能返回的零值自initWithNibName:束:]'然後打印出的價值觀和他們是正確的。我假設自己不會總是被改變,但是按照自己的方式做事通常更安全。 – Jsdodgers 2013-03-19 06:29:33

+0

另外,感謝關​​於'_value'的提示。只是爲了確保我清楚這一點,使用'_value'時,'[self setValue:]'不會被調用,對嗎?如果是這樣,是不使用self.value的唯一原因還是另一個? – Jsdodgers 2013-03-19 06:31:34

+0

價值屬性在你的情況下,所以當綜合使用像這樣的標準代碼... @synthesize value = _value; 您也可以使用[self setValue:]來獲取值。 – 2013-03-19 06:35:05

1

請使用下面的代碼覆蓋init方法

-(id)initWithValue:(int)val 
{ 
    self = [super init]; 
    if(self) 
    { 
    self.value = val; 
    } 

    return self; 
} 
0

[super initWithNibName:bundle:]實際上調用了超類的方法。 如果你使用[self initWithNibName:bundle:]實際上它會調用initWithNibName:bundle的重寫:當然你必須重寫它,否則它也會調用超類方法。所以如果你想在initWithNibName的重寫中做一些初始化,那麼你可以使用[self initWithNibName:bundle:],但如果你不需要做額外的初始化,那麼to方法之間沒有區別;

2

你應該這樣做以下方式:

- (id)initWithValue:(int)val { 
    self = [super initWithNibName:nil bundle:nil]; 
    if (self) { 
     _value = val; 
    } 
    return self; 
} 

在iOS系統中,一個常見的模式是返回零,如果發送到初始化方法的參數是無效的。該值將是以下兩件事之一:當前指向self或nil的指針。如果超級調用返回nil,那麼該對象沒有正確設置,所以你應該返回nil。做self = [super initWithNibName:nil bundle:nil];只是可以更容易地尊重超級

+0

注意,它實際上是完全有效的返回不同的對象(而不是'nil'或'self'的電流值)從'init'方法。這樣做是爲了用一個新的 - 也許是一個從一個筆尖加載的,或一個特定的子類,或一個單身人士替換現有的對象。您應該立即將這個對象存儲到'self'中,並在init'方法的其餘部分使用它來代替原來的實例。 – 2013-03-19 07:07:26

+0

這些通常被稱爲類集羣,並且不應因此而繼承它們。自我可能會最終成爲的超級類,以便訪問方法和實例變量不同子類型在當前類定義會導致EXC_BAD_ACCESS – 2013-03-19 07:22:18

+0

尼克,類簇只有一個超類可能會返回一個不同的實例的*很多*的原因之一來自'-init'。請參閱Mike Ash的文章[可可初始化程序的原理和方法](http://www.mikeash.com/pyblog/the-how-and-why-of-cocoa-initializers.html),特別是神話/事實部分, 更多細節。 – 2013-03-20 03:20:49