0

私がGoogleを検索したことを最初に言わせてください。多くの人が同様の問題を抱えていますが、次のような奇妙な振る舞いと救済策については何も見ていません。

UIViewControllerを作成し、いくつかのIBOutletsにペン先を関連付けました。別のクラスからこのペン先を消費しようとしたところ、initWithNibName:bundle:でインスタンス化した後、IBOutletsがまだnilであることがわかりました。

私はそれらが正しく配線されていることを確認しました、そしてはい、それらは合成されていますが、それでも何もありません。さらに調査しているときに、initWithNibNameメソッドを次のように変更しました。

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

        UIView *view = self.view;
        NSArray *subviews = self.view.subviews;
        NSLog(@"Loaded view containing %d subviews.", [subviews count]);

    }
    return self;
}

信じられないことに、ここに3行を追加すると、使い捨て変数とロギングが作成され、IBOutletsが適切に接続され、外部から機能するようになります。

マシンをクリーンアップして再構築して再起動しましたが、それでもこれらの行を削除すると、動作を停止します。私はここで本当に困惑していて、出荷した瞬間に壊れてしまうようなブードゥーが機能しているのではないかと心配しています。何が起こっているのかについてのアイデアはありますか?

4

1 に答える 1

2

initWithNibName:bundle:あなたは何をするのか、そしていつUIViewControllerロードがそのペン先をロードするのかを誤解しています。

このinitWithNibName:bundle:メソッドは、ロードされるペン先の名前を記録します。ペン先はすぐには読み込まれません。

この-[UIViewController view]メソッドは、必要に応じて送信することにより、ペン先をオンデマンドでロードします[self loadView]。の実装-[UIViewController view]は基本的にこれです:

- (UIView *)view {
    if (_view == nil) {
        [self loadView];
        [self viewDidLoad];
    }
    return _view;
}

したがってself.viewinitWithNibName:bundle:オーバーライドを呼び出す、 ViewControllerはそのペン先をロードします。

self.viewただし、から呼び出すことは一般的に不適切initWithNibName:bundle:です。ビューコントローラは、ビュー階層がなくても存在できる必要があります。

たとえば、ユーザーがアプリを実行していて、ビューコントローラーをナビゲーションコントローラーにプッシュすることで実装する複数のビューコントローラーをナビゲートするとします。その後、ユーザーはしばらくの間別のアプリに切り替えます。現在、システムのメモリが不足しているため、アプリを含むバックグラウンドアプリが強制終了されます。

ユーザーがアプリを再度起動すると、アプリは(うまくいった場合)ユーザーの状態を復元しようとする必要があります。これは、プッシュビューコントローラーのスタックを使用してナビゲーションコントローラーをリロードすることを意味します。ただし、画面にはトップビューコントローラのビューのみが表示されます。すべての非表示のViewControllerのビューをすぐにリロードするのは、時間、メモリ、およびバッテリーの無駄になります。そのため、各ビューコントローラーはペン先をオンデマンドでロードします。

于 2012-11-27T21:37:53.717 に答える