5

UIViewControllerサブクラスに2つのinit関数があります。

- (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:メソッドの呼び出しを回避するために、init関数を挿入しました。xibファイルを取り出して実験しようとしています。残念ながら、このinit [[Myclass alloc] init]を呼び出すと、[super init]の呼び出しを通じてinitWithNibName:bundle:が呼び出されます。

まず、親のinitメソッドを呼び出して、自分のinitWithNibName:bundle:メソッドを呼び出すことを期待できるように、ドキュメントのどこを読む必要がありますか?

第二に、これはAppleの側でどのように良い設計上の選択ですか。なぜこれが望ましい動作なのかわかりませんか?(私はここで全体像を把握していない可能性があるので、遠慮なく私を手がかりにしてください。)

第三に、どうすればそれをうまく回避できますか。コードからinitWithNibName:bundle:を削除するだけですか?クラスのxibまたは手動インスタンス化のいずれかを使用するオプションが必要な場合はありません。

4

4 に答える 4

6

通常、管理対象オブジェクトコンテキストを使用してViewControllerを初期化する必要があります。-(id)initWithContext:スーパーのメソッドを呼び出す簡単なメソッドを実装しinitWithNibName:bundle:ます。このようにして、自分のxib名を定義できます。

initWithNibName:bundleあなたの質問の最初の部分(つまり、読むこと)についてはわかりませんが、VC用のAppleのクラステンプレートは、与えられたものと同じパラメータでsuperを呼び出す独自のメソッドを持っていることを示しています。したがって、あなたの状況から、これはまさにイニシャライザーとして指定さinitれており、superで単純なメソッドを呼び出すことは「安全」ではないと思いますinitWithNibName:bundle。UIViewControllerのinitは次のようになっていると思います。

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

  if (!self) return nil;

  // some extra initialization

  return self;
}

スーパークラスにはメソッドがないため、initWithNibName:bundleそれ自体でメソッドを呼び出して、指定された初期化子にする必要があります。オーバーライドしたので、ObjCのランタイムはselfそのメソッドでクラスに置き換えられます。

于 2012-12-04T14:20:00.133 に答える
2

UIViewControllerのGUIの作成からInterfaceBuilderを除外する場合は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.
}
于 2012-12-04T14:19:09.770 に答える
0

まず、親のinitクラスへの呼び出しが自分のinitWithNibName:bundle:メソッドを呼び出すことを期待するために、ドキュメントのどこを読む必要がありますか?

そうではありません、それは設計上のものです。initすべてのクラスの基本初期化メソッドではありません

第二に、これはAppleの側でどのように良い設計上の選択ですか。なぜこれが望ましい動作なのかわかりませんか?(私はここで全体像を把握していない可能性があるので、遠慮なく私を手がかりにしてください。)

それinitを呼び出すと、nil名とバンドルが送信され、デフォルトで空のxibファイルになります。あなたのものであろうとなかろうと、常にxibファイルがあります。

第三に、どうすればそれをうまく回避できますか。コードからinitWithNibName:bundle:を削除するだけですか?クラスのxibまたは手動インスタンス化のいずれかを使用するオプションが必要な場合はありません。

あなたはそうしない。スーパーを呼び出すだけで、メソッドを転送するだけの場合は、実際にそのコードをそこに置く必要はありません。

于 2012-12-04T14:19:28.590 に答える
-3

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

- (void)viewDidLoad
{
    [super viewDidLoad];
    if (!self.nibName) {
        // View was not loaded from nib - setup view
    }
}
于 2012-12-04T15:58:18.960 に答える