我正在考慮以下自定義視圖控制器:是否有 - (id)init不會返回自己的良好做法?
- (id)init
{
self = [super init];
if (self == nil) {
return self;
}
return [[UINavigationController alloc] initWithRootViewController:[self autorelease]];
}
這樣行嗎?
我正在考慮以下自定義視圖控制器:是否有 - (id)init不會返回自己的良好做法?
- (id)init
{
self = [super init];
if (self == nil) {
return self;
}
return [[UINavigationController alloc] initWithRootViewController:[self autorelease]];
}
這樣行嗎?
這是非常糟糕的做法。初始化方法應返回正在實例化的類的實例。總是。或者nil
如果有問題。
如果你想要做一些額外的邏輯,並與當前類返回導航控制器視圖控制器,你應該考慮做一個類的方法根視圖控制器,是這樣的:
+ (UINavigationController*)someThing{
id IdontKnowWhatIsTheNameOfYourClass = [[[[self class] alloc] init] autorelease];
return [[[UINavigationController alloc] initWithRootViewController:IdontKnowWhatIsTheNameOfYourClass] autorelease];
}
但是,即使這不是很好的做法。你的視圖控制器應該不知道它是一個模式視圖控制器,在導航控制器內還是在標籤欄控制器內。即使你可能會爭辯說,你只會在這種情況下使用這種方法,它應該是任何這些階段的根源。
要清楚,這將工作。但它非常糟糕。
這取決於一些事情。從技術上講,允許init方法重新分配self
(這就是爲什麼你總是將alloc/init配對在同一個賦值中的原因)。然而,它應該被認爲是可怕的設計返回一個不同類的對象(即沒有從被啓動的類繼承的對象)。
所以,除非你的班級是UINavigationController的父母,否則我會說你的init方法是一個不好的選擇。
可能更好的做一個更具有語義命名的類方法,它有一個合適的返回類型(而不是隱式合約,它會返回一個對象在它所屬的類的同一族中
如果你有足夠的理由這樣做,這是一個很好的做法,它被Class clusters或者試圖使用棘手的緩存機制所使用,很少有理由這樣做,而且是一個相當先進的事情。如果你有一個非常複雜的超類,它也是危險的
如果你真的必須使用這個技巧(而不是僅僅利用類的構造函數),你必須要小心,尊重引用計數(如果你不使用ARC):
釋放自我的前一個實例
確保新的返回自我有一個+1保留計數因爲你的客戶一旦完成就想發佈它。
例如,如果你想使用一些緩存實例:
- (id)initWithKey:(NSString *)aKey
{
id cachedInstance = [__myCache objectForKey:aKey];
if (cachedInstance) {
// use this instance instead of self
[self release];
return [cachedInstance retain];
}
self = [super init];
if (self) {
// further init the instance here
...
// cache it
[__myCache setObject:self forKey:aKey];
}
return self;
}
你確實有一點,但如果你認爲他的案例來自一個簡單的-init方法,那就是 - (id)init;那麼真的應該沒有理由返回除了它自己的實例之外的任何東西。 – Daniel
這看起來不錯,但你想通過這種設計實現什麼?它有點殺死可讀性... – dasblinkenlight