4

それは確かに無害に見えます。私の App Delegate では、起動時にヒントを表示するフラグのNSUserDefaultsをチェックします。設定されている場合は、 の最後に次のapplicationDidFinishLaunching:ようにします。

TipsViewController *vc = [[TipsViewController alloc]
  initWithNibName:@“TipsView" bundle:nil];
[window addSubview:vc.view];
[vc release];

アイデアは、このビューを一時的に表示することです。(これはモーダル VC ではないことに注意してください。この時点ではナビゲーション コントローラーはありません。また、このビューにはナビゲーション バーもありません。)

このビューが閉じられたら、プリエンプトされたUITabBarControllerのビューをウィンドウに追加して遷移し、ヒント ビューをメイン ウィンドウから削除します。私はまだビューの却下ポイントに到達していません。

私の TipsView の VC は、多かれ少なかれ次のように配線されています。

UIView -> view -> File’s Owner (TipsViewController)
  UIImageView -> background image
  UIView -> tipView -> File’s Owner
    UIImageView -> background image
    UIScrollView
      UILabel (tip text)
    UIButton -> touch-up-inside -> -(IBAction)button1:
    UIButton -> touch-up-inside -> -(IBAction)button2:
    UIButton -> touch-up-inside -> -(IBAction)button3:

ソースには、3 つのIBAction呼び出しすべての宣言と定義が含まれています。今のところ二人は何もしていません。3 番目のものは、ヒントtextを変更し、サイズを変更して収まるようにし、スクロール ビューcontentSizeを一致するように調整します。

アプリを実行すると、TipsViewControllerビューが正常に表示されます。ヒントのテキストをスクロールすることもできます。ただし、任意のUIButtonで touch-up-inside をトリガーすると、Xcode はソース (各IBActionにブレークポイントを配置した場所) に私を植え付け始めます…そして、または のいずれかで救済しEXC_BAD_ACCESSますobj_stack_overflow

これを、VC、ビュー、およびボタンがあるアプリの他の部分と比較しました。この場合、 VC をナビゲーション コントローラーにプッシュするのではなく、アプリのウィンドウのサブビューとして VC のビューを追加したことを除いて、すべての点で同じです。さらに、View Controller Programming Guide for iPhone OS docs は、これは公正なゲームであると述べています。

アプリケーションで単一のビュー コントローラーを使用する場合、ビュー コントローラーをタブ バーまたはナビゲーション コントローラーに追加する代わりに、そのビューをウィンドウに追加します。

確かに、翼で待機しいるUITabBarControllerがあり、その中にUINavigationControllers (および他の VC) を含むタブがあります。ただし、ヒント ビューが表示されている場合、タブ バー コントローラーのビューはまだウィンドウに追加されていません。意図は、ヒントの表示が終わった後にそれを交換することです。言い換えれば、すべての意図と目的のために、私たちは一時的に 1 つの VC が参加しているように振る舞っています。その後、タブ バーに切り替えて、先端の VC を破棄します。

おそらく私は微妙に間違ったことをしていますか?より良い方法はありますか?(「もっといい方法があるに違いない!」)

スタック トレースの例:

#0  0x992b6f52 in objc_exception_throw
#1  0x302d6ffb in -[NSObject doesNotRecognizeSelector:]
#2  0x3026e056 in ___forwarding___
#3  0x3024a0a2 in __forwarding_prep_0___
#4  0x308f79d1 in -[UIApplication sendAction:to:from:forEvent:]
#5  0x309598b1 in -[UIControl sendAction:to:forEvent:]
#6  0x3095bad2 in -[UIControl(Internal) _sendActionsForEvents:withEvent:]
#7  0x3095a81e in -[UIControl touchesEnded:withEvent:]
#8  0x30910fdf in -[UIWindow _sendTouchesForEvent:]
#9  0x308faecb in -[UIApplication sendEvent:]
#10 0x309013e1 in _UIApplicationHandleEvent
#11 0x32046375 in PurpleEventCallback
#12 0x30245560 in CFRunLoopRunSpecific
#13 0x30244628 in CFRunLoopRunInMode
#14 0x32044c31 in GSEventRunModal
#15 0x32044cf6 in GSEventRun
#16 0x309021ee in UIApplicationMain
#17 0x00002888 in main at main.m:14

トレースからわかるように、最終的にはdoesNotRecognizeSelector:… になりますが、ヒントの VC ソースでメソッドを明確に確認できます。さらに、それらはすべて配線されています。(IBには複数の配線などはありません。ファイルの所有者の関係に至るまで、すべてがうまくいっています。)

手がかりは歓迎/感謝します!

4

1 に答える 1

8

問題は最初のコード スニペットにあります。TipsViewController のインスタンスを作成し、そのビューを保持してからビュー コントローラーを解放すると、割り当てが解除されます。これtargetで、ボタンの は、割り当てが解除されたビュー コントローラーへのポインターになります。

ビューはビュー コントローラを保持せず、デリゲートまたはターゲットも保持しません。

retainビューを表示したい限り、View Controller インスタンスを (おそらくプロパティ内に) 保持しておく必要があります。ビューの操作が完了したら、そのビューを親ビューから削除し、View Controller を解放できます。

于 2009-09-14T14:17:39.673 に答える