次のカスタマイズされたView Controllerを検討しています:
- (id)init
{
self = [super init];
if (self == nil) {
return self;
}
return [[UINavigationController alloc] initWithRootViewController:[self autorelease]];
}
これでいいですか?
次のカスタマイズされたView Controllerを検討しています:
- (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 をペアにする理由です)。ただし、別のクラス (つまり、init されたクラスから継承されていないクラス) のオブジェクトを返すことは、ひどい設計であると考えるべきです。
したがって、あなたのクラスがUINavigationControllerの親でない限り、あなたの init メソッドは悪い選択だと思います。
より意味的に名前が付けられ、適切な戻り値の型を持つクラス メソッドを作成する方が良い場合がありますinit
(呼び出されたクラスの同じファミリのオブジェクトを返すことを暗黙の契約にする代わりに)。
正当な理由がある場合は、それを行うことをお勧めします。これは、クラス クラスタによって、またはトリッキーなキャッシュ メカニズムを使用しようとするときに使用されます。そうする理由はほとんどなく、かなり高度なことです。かなり複雑なスーパークラスがある場合も危険です。
本当にそのトリックを使用する必要がある場合 (クラス コンストラクターを利用するのではなく)、参照カウントに注意する必要があります (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;
}