2012-12-04 13 views
5

私は私のUIViewControllerのサブクラスで2つの初期化機能を持っている:私は避けることでinit関数を入れのUIViewController:[スーパーのinit] [自己initWithNibNameバンドル:]を呼び出す

- (id)init 
{ 
    self = [super init]; 
    if (self) 
    { 
      // Custom stuff 
     return self; 
    } 
    return nil; 
} 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    self = [super initWithNibName: nibNameOrNil 
          bundle: nibBundleOrNil]; 
    if (self) 
    { 
     // Custom stuff 
    } 
    return self; 
} 

をinitWithNibName:bundle:メソッドを呼び出します。私はxibファイルを取り出して実験しようとしています。残念ながら、このinit [[Myclass alloc] init]を呼び出すと、[super init]の呼び出しによってinitWithNibName:bundle:が呼び出されます。

最初に、親initメソッドの呼び出しが自分自身のinitWithNibName:bundle:メソッドを呼び出すと予想されるように、ドキュメントのどこを読んでおくべきですか?

第2に、これはAppleの面でどのように優れた設計の選択ですか。なぜこれが望ましい行動であるのか見ていないのですか? (私はここで大きな画像を取得していない可能性がありますので、私に手がかりをつけてください)

第3に、私はどのように最善を尽くすのですか?私はinitWithNibName:bundle:をコードから取り出すだけですか? xibやクラスのマニュアルインスタンス化を使用するオプションが必要な場合はありません。

+0

- (id)init関数に確実に到達していますか?ヘッダーファイルにもあなたのinit関数を宣言しましたか? – Snaker

+0

@snaker -initはNSObject自体から来ます。宣言する必要はありません。 – CodaFi

答えて

-2

viewDidLoadメソッドでビューをカスタマイズし、サブビューを追加できます。このメソッドでは、クラスがinitを使用して作成されたかどうか、またはinitWithNibName:bundle:を使用して、プロパティnibNameを調べることによってチェックできます。 initを使用する場合、nibNameはnilになります。

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    if (!self.nibName) { 
     // View was not loaded from nib - setup view 
    } 
} 
+1

このメソッドは_after_ initialisationと呼ばれます。 – Eimantas

+0

@DrummerB初めてself.viewを参照するときにloadViewを作成しない場合、loadViewをオーバーライドする必要はありません。 –

2

UIViewControllerのGUIの作成からInterface Builderを除外する場合は、loadViewをオーバーライドして、ビューを自分で作成する必要があります。 initWithNibName:bundle:を実装しないでください。

- (void)loadView { 
    // Init a view. The frame will be automatically set by the view controller. 
    UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; 

    // Add additional views (buttons, sliders etc.) to your view here. 

    // Set the view controller's view to the new view. 
    self.view = view. 
} 
+0

s/subclass/override /。) – Eimantas

0

私は 親のinitクラスへの呼び出しは、私自身の initWithNibName呼び出すことが予想されるだろうように、ドキュメントに私が読んでする必要がありますまず、:バンドル:メソッドを?

あなたはそうではありません。デザインのものです。 initは、すべてのクラスの基本初期化メソッドではありません。

第2に、これはApple側でどのように優れた設計方法ですか。私は なぜこれが望ましい動作を見ていないのですか? (それは私がちょうどない そうで手掛かり私には自由にしてくださいここで大きな画像を取得していますいる可能性があります。)

場合は、空のXIBにinit、それがnil名とバンドルを送信呼び出し、そのデフォルト値ファイル。あなたのxibファイルはいつもあります。

第3に、どのようにすればよいのですか。私はちょうど initWithNibName:バンドルを自分のコードから取り出しますか? にxibまたはクラスの手動インスタンシエーション を使用するオプションが欲しい場合はありません。

あなたはありません。スーパークラスを呼び出すだけであれば、メソッドを転送するだけで、実際にそのコードを持つ必要はありません。

6

通常、管理対象オブジェクトのコンテキストでビューコントローラを初期化する必要があります。私はsuperのinitWithNibName:bundle:メソッドを呼び出す簡単な-(id)initWithContext:メソッドを実装します。私は自分のxib名を定義することができます。

VCのアップルのクラステンプレートには、同じパラメータを指定してsuperを呼び出す独自のinitWithNibName:bundleメソッドがあることがわかります。したがって、あなたの状況から私はちょうどこれが指定されたイニシャライザであり、initWithNibName:bundleを呼び出すので、簡単にinitメソッドを呼び出すのは「安全」ではないと言うでしょう。スーパークラスは、それはそれ、指定イニシャライザ作り自体にメソッドを呼び出す必要がありinitWithNibName:bundle必要はありませんので

- (id)init 
{ 
    self = [self initWithNibName:nibNameDerivedFromClass bundle:probablyNilOrMainBundle]; 

    if (!self) return nil; 

    // some extra initialization 

    return self; 
} 

:私はのUIViewControllerのinitは、このようになりますと信じています。オーバーライドしたので、ObjCのランタイムはそのメソッドのselfをクラスに置き換えます。