viewDidloadが呼び出されずに呼び出されたdeallocが呼び出されました(KVOオブザーバーの削除時のクラッシュ) -- ios フィールド と objective-c フィールド と iphone フィールド と uitabbarcontroller フィールド 関連 問題

Dealloc called without viewDidLoad being called (crash on removing KVO observer)












2
vote

問題

日本語

UITabBarController を使用していて、マイ3RDタブはシングルトンデータストア上の配列を監視します(<コード> viewDidLoad )。

現在ログアウトした場合( App Delegate からルートビューコントローラを変更してください)、 dealloc がメッセージを表示することができない場合、アプリはクラッシュします。オブザーバとして登録されていないため、キーパス "x"のオブザーバを削除してください。

ブレークポイントを使用して、この3番目のタブで<コード> viewDidLoad が呼び出されないことがわかりますが、サインアウト時にDEALLOCが呼び出されます。何が起こっている? UITabBarController は、ストーリーボードに入るが、そのタブを「ロード」しないと仮定します。それでも、Tab Bar Controllerをリリースすると、IOSがDeallocを呼び出します。

ブール値を使用して viewDidLoad の実行を追跡するか、 @try ステートメントでオブザーバーを削除してみてください。これには全体的に良いデザインがありますか?

英語

I am using a UITabBarController, and my 3rd tab observes an array on a singleton data store (implemented in viewDidLoad).

Currently if I just log out (and change root view controller from App Delegate), the app will crash when dealloc is called on that 3rd tab with the message "cannot remove observer for the key path "X" because it is not registered as an observer.

Using breakpoints, I see that viewDidLoad is never called on this 3rd tab, however dealloc is being called when I sign out. What is going on? I assume the UITabBarController is holding a reference to the 3rd tab when I enter the storyboard, but does not "load" that tab. Yet iOS calls dealloc on it when I release the tab bar controller.

Should I use a boolean to track viewDidLoad execution, or try to remove the observer with a @try statement? Is there an overall better design for this?

</div
           

回答リスト

3
 
vote

@try を使用しないでください。 Objective-Cの例外は常に Programmer Error を検討し、致命的であるべきです。

言うように、これを避けるために、<コード> -viewDidLoad に設定されているブールIVARを使用します。


表示に必要なときにのみロードされているだけなので、ビューはロードされていません。


生のKVOは危険で扱いにくい可能性があります。この質問に答える必要はありませんが、 RectiveCocoa はKVO経験を大幅に向上させます。

 

Do not use @try. Exceptions in Objective-C should always be considered programmer error, and should be fatal.

As you say, use a boolean ivar set in -viewDidLoad to avoid this.


The view has not been loaded because views are only loaded when they are required for display.


Raw KVO can be dangerous and unwieldy. While not required to answer this question, ReactiveCocoa significantly improves the KVO experience.

</div
 
 
2
 
vote

viewDidLoad は、ビューが初めて表示される前に呼び出されます。 UITabBarController は、関連する UIViewController を作成していますが、そのビューは作成中にロードされません。ユーザーが初めてタブを訪れたときにオンデマンドがロードされます。

kvoの削除は問題があります、私は dealloc @try を使用しないでください。 kvocontroller :それはかなり使いやすく、それはあなたのためのすべてのエッジケースも処理するでしょう。

 

viewDidLoad is called before the view appears for the first time. UITabBarController is creating the relevant UIViewController, but the view is not loaded during creation. It is loaded on-demand, when a user visits the tab for the first time.

KVO removal is problematic, I don't think you can avoid using @try in dealloc. I would suggest to use KVOController: it's fairly easy to use and it would also handle all the edge cases for you.

</div
 
 
1
 
vote
vote
ベストアンサー
 

でさえもっと良い解決策を見つけたかもしれません。 initWithCoder:(NSCoder *)aDecoder のメソッドにオブザーバを追加します。これは、親 UITabController6 がロードされたときに呼び出されます。私はストーリーボードを使っています。これは、通常の init の代わりにこのメソッドを上書きする必要がある理由かもしれません。 BOOL フラグまたは<コード> @try 、クラッシュしていないことなく、これをやってることができるようになりました。

<事前> <コード> UITabBarController0
 

May have found an even better solution. I add the observer in the method initWithCoder:(NSCoder *)aDecoder, which is called when the parent UITabController is loaded. I am using the storyboard which may be why I need to call override this method instead of regular init. Doing this now without the need for a BOOL flag or @try and no crashing.

- (instancetype)initWithCoder:(NSCoder *)aDecoder {     if (self = [super initWithCoder:aDecoder]) {         [anObject addObserver:self forKeyPath:aKeyPath options:0 context:NULL];     }     return self; } 
</div
 
 
0
 
vote

kvoが設定されているかどうかを設定するためにフラグを使用します。 @tryを使用すると、アプリの状態に応じてメモリ管理の問題を作成できます。

 

Use a flag to set whether or not KVO has been set up. Using @try can create memory management issues depending on the state of the app.

</div
 
 

関連する質問

1  Tabbarアイテムでビューを更新する方法iOSプログラミング  ( Ios programming how to refresh a view with in a tabbar item ) 
ねえ私はタブバーベースのアプリを持っていて、それは私がそのデータをnsuserdefaultsによって保存し、別のタブの最初のビューコントローラに保存したデータを表示したいタブのビューコントローラを持っています。しかし、問題は最初に保存した後に、上記のタブがク...

6  ViewWillAppear:タブバーとナビゲーションコントローラを一緒に使用している間にメソッドが応答していないようです  ( Viewwillappear method doesnt seem to respond while using tab bar and navigatio ) 
タブバー+ナビゲーションベースのアプリケーションを使用しています.4つのタブバーがあります。 1つのView Controllerから別のビューコントローラに移動すると、<コード> viewWillAppear: メソッドは応答していないようであり、次のビュー...

2  タブバーアイテムのアイコンはどのようなサイズですか?  ( What size should my tab bar item icons be ) 
このドキュメントリンゴの ...

0  Xcode 4.2を使用したTableViewとNavigation Controllerを使用したタブベースのアプリケーション  ( Tab based application with tableview and navigation controller using xcode 4 2 ) 
タブバーアプリケーションにTableViewを作成したいです。 新しいバージョンのXcode(Xcode 4.2)を使用しているので、「mainwindow.xib」を表示してナビゲーションコントローラを配置できません。 「app delegate.m」に次の...

3  プログラムでMonotouchアプリでタブを変更します  ( Programmatically changing tabs in a monotouch app ) 
私の無知のために私を許して、私はMonotouchの新しいので、私はこれが簡単なことであると確信していますが、私はどこにでも答えを見つけることができません。 rootナビゲーションにUitabbarControllerを使用するMonotouchでiPhon...

1  タブバーのルートビューとしてNavigationControllerをインストールする方法?  ( How to install a navigationcontroller as the root view in a tab bar ) 
タブバービューでルートビューとしてNavigationControllerをインストールする方法? My Applise:DidFinishLaunchingWithOptions:メソッド私はタブバーインタフェースを作成し、ウィンドウのRootViewCo...

119  <uitabbarController:0x197870の開始/終了外観遷移への不均衡な呼び出し  ( Unbalanced calls to begin end appearance transitions for uitabbarcontroller 0x ) 
私はそのように似たようなユーザについて似たようなエラーしかし、このエラーは異なります。 最初にビューコントローラを追加したときにこのメッセージを受信しました: <事前> <コード> Unbalanced calls to begin/end appearanc...

20  タブバーのメニューをカスタマイズします  ( Customizing the more menu on a tab bar ) 
私は私のアプリでタブバー(UitabbarController)を使用しています、そして、その他のボタンをクリックしたときに表示されるテーブルの外観をカスタマイズします。 を設定することで、画面が表示されているナビゲーションバーの外観を変更する方法を取り出しま...

4  タブバーのより多くのコントローラをオーバーライドする方法  ( How to override tabbars more controller ) 
UitabbarControllerの「その他」タブコントローラに非常に迷惑な問題を抱えています。デフォルトでランドスケープモードへの回転をサポートしていますが、適切なデリゲートメソッドを呼び出すことで、イベントをサブビュー(またはそれによって管理されている...

7  Uitabbarの背景色を変更するには、選択されたタブの色を青に変更しますか?  ( How to change background color of uitabbar selected tab color to blue ) 
こんにちは 私はこのようなタブ選択効果を望んでいました。黒の背景の代わりに青いものであるべきです。私が青い背景を思いつくべきだと私が何をすべきですか?私はそれほど多くのことを試みましたが、適切な解決策を試してみました。私を提案してください私は何をす...




© 2022 cndgn.com All Rights Reserved. Q&Aハウス 全著作権所有