5

UIViewControllerでloadViewを使用する場合の非常に興味深い問題。

通常はこのように使用しました

// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
    NSLog(@"loadview");
    [super loadView];
}

削除する場合

 [super loadView];

これでデッドループになります

- (void)loadView {
    NSLog(@"loadview");

}

なんで ?

4

3 に答える 3

9

この場合、無限ループを作成する唯一の方法は、設定されなくなるまでビュープロパティを取得することです。次に書く場合(たとえば):

- (void)loadView {
   self.view = [[UIView alloc] initWithFrame:self.view.bounds];
}

無限ループになりますが

- (void)loadView {
   self.view = [[UIView alloc] initWithFrame:CGRectZero];
}

正常に動作します。

したがって、設定しない限り、viewプロパティにアクセスすることはできません。

于 2011-08-09T11:59:47.100 に答える
4

スーパークラス(UIViewController)に実装されているものを継承しているだけなので、スーパーメソッドを呼び出さないと、実行する必要のある実装は実行されません。

ほとんどすべてのスーパーメソッドは重要なことを実行し、スーパークラスの実装を継承するローカルクラスはそれらをすべて一緒にオーバーライドする必要があります(ドキュメントを参照してスーパーが行うことについてすべてを知っている場合を除いて、それは決して良い考えではありません)、または単にローカルクラスの実装を追加する継承されたスーパークラスの実装。

結論として、ソフトウェア開発のほとんどの場合であるクラスを継承するときはいつでも、それらをオーバーライドするのが安全でない限り、スーパークラスにその実装を行わせる必要があります。

私が正しければ、スーパーloadViewはループを回避するために非常に重要な何かを実装しているようです。

追記:ただし、ドキュメントに基づいて、スーパーメソッドを呼び出さないでください:http: //developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html おそらく、無限ループは、viewプロパティを適切に実装しないことによって発生します。

于 2011-01-28T07:35:52.573 に答える
2

loadViewをオーバーライドすると、コントローラーのビュー階層のルートビューを提供することが期待されます。これを指定しないと、ビューが参照されるたびにloadViewが呼び出され、無限ループが発生する可能性があります。ドキュメントから:

ビューを手動で指定する場合は、loadViewメソッドを実装し、それを使用してルートビューオブジェクトをviewプロパティに割り当てる必要があります。

無限ループを引き起こす実装:

- (void)loadView {
    NSLog(@"loadview");
}

...self.viewはloadViewの後でnilです

- (void)loadView {
   self.view; // Or anything that references self.view
}

... self.viewを参照すると、loadViewが呼び出されるため、無限ループになります。

正しい:

- (void)loadView {
    self.view = [[UIView alloc] init];
    if (self.view == nil) {
        [super loadView]; // Try to load from NIB and fail properly, also avoiding inf. loop.
    }
}
于 2011-11-22T17:55:04.900 に答える