0

この問題は iOS4.3 でのみ発生しています。私は ARC を使用しており、ベース SDK は iOS6 です。

ビュー コントローラーで、-viewDidAppearアプリが初めて起動されたかどうかを確認し、そうであれば、UIAlertView を作成して表示します。その UIAlertView をstrongビュー コントローラーのプロパティに割り当て、自身を UIAlertView デリゲートとして設定します。

self.uiAlertView = [[UIAlertView alloc] initWithTitle:@"Welcome!"
                                              message:messageString 
                                             delegate:self
                                    cancelButtonTitle:@"OK"
                                    otherButtonTitles:@"View Tutorial Videos", @"Email Support", nil];

-alertView:didDismissWithButtonIndex:ボタンの 1 つをタップすると、割り当てが解除されたインスタンスに送信されたというエラー メッセージが表示されてアプリがクラッシュします。デリゲートは、UIAlertView を表示しているビュー コントローラーです。

その後のアプリのすべての起動で、UIAlertView が表示されない場合、問題はありません。ビューコントローラーは確実に割り当て解除されていません。

UIAlertView を表示し、delegate を nil に設定しても問題はなく、アプリは引き続き動作するため、ビュー コントローラーは引き続き使用できるため、明らかに割り当てが解除されていません。

何が起こっている?これは iOS4.3 でのみ問題を引き起こします。

編集:コメントの提案に基づいて、別の場所にいくつかのログメッセージを追加しました。

ビュー コントローラーが解放されていることを発見しましたが、そのビュー コントローラーが UIAlertView を表示する場合のみです。UIAlertView のデリゲートとして自分自身を設定し、それを表示するという理由だけで、View Controller が割り当て解除される原因は何でしょうか?

私のアプリ デリゲートにはstrongビュー コントローラーへの参照があるため、ビュー コントローラーが解放される理由はまったくありません。


編集 2: 起動中に、メイン ビュー コントローラーが 2 回インスタンス化されていることがわかりました。最初のものは UIAlertView を作成するものであり、そのものは解放されています。2つ目は、後でやり取りできたもので、View Controllerがまだそこにあり、操作可能であると思いました。

ただし、View Controller が 2 回作成される場所や理由がわかりません。ビュー コントローラー用の alloc/init ステートメントがありません。MainWindow_iPhone.xib にのみ存在します。

私のView Controllerで初めてviewDidLoadが呼び出されたとき、上のスタックフレームは[UIViewControllerビュー]です。ビューコントローラーの2番目のインスタンスでviewDidLoadが2回目に呼び出された場合、上記のスタックフレームは[UINib instantiateWithOwner:options:]です。


編集 3: 問題を「修正」しましたが、なぜこれが起こるのかわかりません。おそらく、あなたは私が理解するのを助けることができます.

MainWindow_iPhone.xib で、ルート ビュー コントローラーを作成し、それをアプリ デリゲートの IBOutlet に割り当てました。代わりに、ビュー コントローラーを xib から削除し、-application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions... のコードで作成すると、問題はなくなりました。

なぜxibでView Controllerが2回作成されるのでしょうか?

4

2 に答える 2

1

私は以前にこの問題を抱えています。alertView:didDismissWithButtonIndex: は、alertView: clickedButtonAtIndex: の後に呼び出されます。ほとんどの場合、[self.navigationController popViewControllerAnimated:YES] のような方法で、alertView:clickedButtonAtIndex のビュー コントローラーの割り当てを解除します。

UIAlertView デリゲートは、弱参照ではなく割り当てです。デリゲートの割り当てが解除されても、自動的に nil に設定されることはありません。それが、コードがクラッシュする理由です。

于 2013-09-11T19:46:51.870 に答える
0

このメソッドにコメントする(または削除する)ことで、この問題を修正しました。

- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    NSLog(@"se apreto cancel");
}

James Wang が言ったように、didDismissWithButtonIndex は clickedButtonAtIndex の後に呼び出されるので、クラッシュを避けるためにコメントしました。

于 2013-11-28T01:39:48.330 に答える