UIViewController のプッシュおよびポップが原因で UINavigationController がクラッシュする
質問
問題:UIWindowのサブビューとしてUINavigationController、rootViewControllerクラス、カスタムMyViewControllerクラスがあります。次の手順では、100% 再現可能な Exc_Bad_Access が発生します。
[myNaviationController pushViewController:myViewController_1stInstance animated:YES];
[myNaviationController pushViewController:myViewController_2ndInstance animated:YES];
左奥の TapBarItem を 2 回押して (myViewController インスタンスを 2 つポップアウトし)、rootViewController を表示します。
半日にわたる試行錯誤の末、ようやく答えを見つけましたが、同時に疑問も生じました。
ソリューション: .h ファイルが乱雑になるのを避けるために、プライベート変数を宣言する遅延的な方法として、.m ファイル内で多くのオブジェクトを宣言しました。例えば、
#impoart "MyViewController.h"
NSMutableString*variable1;
@implement ...
-(id)init
{
...
varialbe1=[[NSMutableString alloc] init];
...
}
-(void)dealloc
{
[variable1 release];
}
何らかの理由で、myViewController_2ndInstance のビューをロードした後、myViewController_1stInstance のビューがアンロードされるとき (ただしナビゲーション コントローラのスタック内にあるとき)、iPhone OS はこれらの「遅延プライベート」変数のメモリ割り当ての追跡を失う可能性があります。myViewController_2ndInstance のビューがまだ読み込まれているため、初めて背面の TapBarItem をタップしても問題ありません。しかし、背面の TapBarItem を 2 回タップすると、最初のインスタンスの割り当てを解除しようとしたため、ひどい目に遭いました。[変数リリース] を呼び出すと、ランダムにポイントしたため (ポインタが緩い)、Exc_Bad_Access が発生しました。
この問題を解決するには、.h ファイル内で variable1 を @private として宣言するのが簡単です。
私の質問は次のとおりです。UINavigationControllerに関与するまで、私はかなり長い間「lazy private」変数を問題なく使用してきました。これはiPhone OSのバグでしょうか?それとも、Objective C について私の側に根本的な誤解があるのでしょうか?
解決
同じ静的に割り当てられた変数を使用するビュー コントローラーの両方のインスタンスに関連している可能性があります。
つまり、両方とも myViewController_1stInstance
そして myViewController_2ndInstance
同じものを使用しています variable1
メモリ内の場所を変更し、相互に上書きします。
変数は、次の中括弧内で宣言されます。 @interface
定義では、クラスの各インスタンスに対してランタイムによってメモリの場所が割り当てられます (呼び出しのたびに) [<ClassName> alloc]
. 。グローバル スコープ (つまり、関数やクラス宣言の外側) で宣言された変数は次のとおりです。グローバル。つまり、変数はアプリケーションの実行コピーごとに 1 つの値のみを保持できます。
Objective-C には真のプライベート変数はありませんが、説明したようにコンパイル時に他のインスタンスから非表示にすることができます。 ここ.
他のヒント
Aは、後半に反応少し、私は前にこの問題を見てきました。同時にアニメーション2 viewControllers
を押さないでください。アニメーションなしで最初のものを押して、アニメーションを有する第2のいずれかを押します。 UINavigationController
は、同時に2つのアニメーションを処理することはできません。