web-dev-qa-db-ja.com

モーダルビューコントローラーを提示するとiPhoneがクラッシュする

別のビューがモーダルで表示された直後にモーダルビューを表示しようとしています(2番目は表示される読み込みビューです)。

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    // Show load
    LoadViewController *loader = [[LoadViewController alloc] init];
    [self presentModalViewController: loader animated:NO];
    [loader release];
}

しかし、これを行うと、「プログラム受信信号:「EXC_BAD_ACCESS」」が表示されます。エラー。

スタックトレースは次のとおりです。

0  0x30b43234 in -[UIWindowController transitionViewDidComplete:fromView:toView:]
1  0x3095828e in -[UITransitionView notifyDidCompleteTransition:]
2  0x3091af0d in -[UIViewAnimationState sendDelegateAnimationDidStop:finished:]
3  0x3091ad7c in -[UIViewAnimationState animationDidStop:finished:]
4  0x0051e331 in run_animation_callbacks
5  0x0051e109 in CA::timer_callback
6  0x302454a0 in CFRunLoopRunSpecific
7  0x30244628 in CFRunLoopRunInMode
8  0x32044c31 in GSEventRunModal
9  0x32044cf6 in GSEventRun
10 0x309021ee in UIApplicationMain
11 0x00002154 in main at main.m:14

何か案は?私は完全に困惑しています!読み込みビューは空なので、エラーの原因となるものは何もありません。同じイベントループで2つのビューをモーダルに起動することと関係がありますか?

ありがとう、

マイク

編集:非常に奇妙です...少し遅れて読み込みビューが表示されるように少し変更しましたが、これは正常に機能します!したがって、同じイベントループ内の何かのように見えます!

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    // Show load
    [self performSelector:@selector(doit) withObject:nil afterDelay:0.1];
}

- (void)doit {
    [self presentModalViewController:loader animated:YES];  
}
30

少し遅れて読み込みビューが表示されるように少し変更しましたが、これは問題なく機能します。したがって、同じイベントループ内の何かのように見えます!

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    // Show load
    [self performSelector:@selector(doit) withObject:nil afterDelay:0.1];
}

- (void)doit {
    [self presentModalViewController:loader animated:YES];  
}
30

IOS 4でも同じエラーが再現されたと思います。私のアプリケーションでは、最初のモーダルビューを表示した直後に2番目のモーダルビューを表示しようとすると、クラッシュが一貫して発生しました。私は数時間気が狂って苦労しました。

このスレッドの投稿を読んだ後、タブバーアプリケーションテンプレートを使用して、簡単で再現可能な例を作成しようとしました。 「FirstViewController.m」のボタンクリックに応答した後、UIImagePickerControllerを使用して最初のモーダルビューを表示することができました。 (imagePickerControllerDidCancelメッセージを処理した後)UIImagePickerControllerを再度表示しようとすると、アプリケーションが同じエラーでクラッシュしました。

デバイス上では、何が起こっているのかまったくわかりませんでした。ただし、シミュレーターでコードを実行したとき、幸運にもコンソールに次のメッセージが表示されました。

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Attempting to begin a modal transition from to while a transition is already in progress. Wait for viewDidAppear/viewDidDisappear to know the current transition has completed'

したがって、私の唯一の選択は、エラーメッセージのアドバイスに従い、viewDidAppear(フラグを使用してこの特別なモードにいることを示す)まで待ってから、2番目のモーダルビューをロードすることです。

完全を期すための完全なスタックトレースは次のとおりです。

 **最初のスローでスタックを呼び出す:
(
 0 CoreFoundation 0x0238c919 __exceptionPreprocess + 185 
 1 libobjc.A.dylib 0x024da5de objc_exception_throw + 47 
 2 CoreFoundation 0x02345078 + [NSException raise:format:arguments:] + 136 
 3 Foundation 0x000ab8cf- [NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116 
 4 UIKit 0x00544317- [UIWindowController transition:fromViewController:toViewController:target:didEndSelector:] + 212 
 5 UIKit 0x0035c769- [UIViewController presentModalViewController:withTransition:] + 2937 
 6 TestTempDelete 0x000021cf- [FirstViewController showImagePicker] + 167 
 7 Foundation 0x0002fcea __NSFireDelayedPerform + 441 
 8 CoreFoundation 0x0236 dd43 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19 
 9 CoreFoundationの0x0236f384 __CFRunLoopDoTimer + 1364 
 10 CoreFoundationの0x022cbd09 __CFRunLoopRun + 1817 
 11 CoreFoundationの0x022cb280 CFRunLoopRunSpecific + 208 
 12 CoreFoundationの0x022cb1a1 CFRunLoopRunInMode + 97 
 13 GraphicsServices 0x02bf12c8 GSEventRunModal + 217 
 14 GraphicsServices 0x02bf138d GSEventRun + 115 
 15 UIKit 0x002beb58 UIApplicationMain + 1160 
 16 TestTempDelete 0x00001eb4開始+53 

お役に立てれば。

5
Daniel

**前に述べたように、isIgnoringInteractionEventsを使用します

//Check if the app is ignoring interatctions, if so, add a delay for 1 sec
if([[UIApplication sharedApplication] isIgnoringInteractionEvents]==TRUE) {
        [currentViewController performSelector:@selector(presentModalViewController:animated:) withObject:screen afterDelay:1];
    } else {
        [currentViewController presentModalViewController:screen animated:YES];
    }
4
user353877

Interface Builderでコードにリンクされたボタンをクリックした後にこれを取得した場合、1つのボタンにリンクされた2つのアクションがある可能性があります(ボタンにリンクされたモーダルビューがあり、ボタンを複製した場合など)別のモーダルビューをリンクしました)。これは両方を起動しようとするため、そのメッセージで失敗します。

3
Simon

同じ例外が発生しました

キャッチされなかった例外 'NSInternalInconsistencyException'が原因でアプリを終了しています。理由: '遷移が既に進行中のときに、からへのモーダル遷移を開始しようとしています。 viewDidAppear/viewDidDisappearが、現在の移行が完了したことを認識するのを待ちます。

以前に提案したように、モーダル遷移の提示を遅らせようとしましたが、それは実際には役に立ちませんでした。次に、ボタンのTouchUpInsideイベントに複数のIBActionが接続されている!!!であることがわかりました。私の場合、2つのIBActionが開始されます。ピープルピッカーをモ​​ーダルに提示することと、イメージピッカーをモ​​ーダルに提示することです。これはエラーメッセージを説明しています。複数のIBActionが接続されているかどうかを確認してください。

3
Eddy

UIButtonをクリックしてModal Viewを開くと、同様のエラーが発生しました。 UIButton'sリスナーをUIControlEventAllEventsからUIControlEventTouchUpInsideに変更しました。基本的には、Touch Down Insideでモーダルビューを起動し、次にTouch Up Insideで再度起動していました。

1
Chris

の名前の不一致が原因で同じ問題が発生しました

HelpViewController *controller = [[HelpViewController alloc] initWithNibName:@"HelpView" bundle:nil];

そして実際の.xibファイルの名前。

1
Alexey Podlasov

問題は、viewDidAppearが含まれているメソッドを初期化して提示するメソッド、またはLoadViewControllerのinit/viewDidLoad/viewWillAppearメソッドにある可能性があります。

いくつかのブレークポイントを設定し、クラッシュするまで続きます...

1
Jordan

この問題は、私も遭遇した問題と関係があると思います。再現は非常に簡単です。

新しいXCodeプロジェクト「ユーティリティアプリケーション」を作成します。 FlipsideViewController.mに、次のメソッドを挿入するだけです。

- (void)viewDidAppear:(BOOL)animated {
  [super viewDidAppear: animated];
  [self showInfo];
}

これを行う場合は、アプリケーションを起動すると、フリップサイドビューがすぐにアクティブになります。フリップサイドビューの[完了]ボタンを押すとすぐにメインビューに戻り、viewDidAppearが再度起動され、フリップサイドビューに戻ります。フリップサイドビューが表示されるとすぐに、アプリケーションは停止します(メモリの割り当て解除機能は呼び出されません)。これは、ホームボタンを押したときと同じです。

これらのビューでいくつかの追加のプロパティを使用していたときに、例外も発生したため、コードを最小限に抑えました...

私は本当に手がかりがありません、この問題が本当に何であるか...

よろしく、トビアス

1
Tobias

私はちょうど今この問題に遭遇し、上記のselector:afterDelayの提案を使用して修正しました。追加するだけで、私はiPhone OS 4.0ベータ版で(修正なしで)コンパイルしましたが、クラッシュはありません!そのため、XCodeのバグは次世代で修正されたようです。これは今日私たちの誰にとっても良いことではありませんが、ご存知のとおり、それは本当にwas Xcodeのバグであり、必ずしもコーディングスタイルで間違っていたものではありません。

0
pulseft

私はちょうどこの問題を抱えていました、そして私の問題は私が私のプロトコルデリゲートをdeallocしたためであることがわかりました。

0
NixonsBack

読み込みビューを実装するために同じ手法を使用しているときに、同様の問題が発生しました。ロードの最後にロードビューが閉じられるとクラッシュします。私の場合、問題は、読み込みビューが閉じられるとすぐにviewDidAppearが再度呼び出され、読み込みビューを再度表示しようとしたため、クラッシュが発生したと考えられます。ロードビューが以前に表示されたかどうかを確認するだけで修正しました。

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    if(needDisplayLoader)
        [self presentModalViewController: loader animated:NO];
}

次に、ローダービューを閉じる前にneedDisplayLoaderをNOに設定します

お役に立てれば...

0
Rom

ループの理由は、ロードしている新しいView ControllerにデフォルトでviewDidAppearメソッドがあり、

[super viewDidAppear animated];

つまり、ループに入るように、メインのViewControllerのviewDidAppearに再度コールバックします。

あなたが提示しているViewcontrollerには、スーパーviewdidapperなしで次のようなメソッドがあります。

-(void)viewDidAppear:(BOOL)animated{
    //[super viewDidAppear:animated]; no super

}
0
NSGodMode

それは本当にviewDidAppearのサポートルーチンが何をしているかに依存します。たとえば、if presentModalViewController:animated:loaderを保持しませんクラッシュは、UIWindowControllerがリリースされたloaderについて話そうとしたことが原因である可能性があります(投稿したルーチンの最後に)。

0
fbrereto

まったく同じ問題がありました。上記の提案でそれを解決しました...

[self performSelector:@selector(doit) withObject:nil afterDelay:0.5];

0.5秒の遅延を使用する必要がありました。おそらく、UIPickerViewControllerモーダルの直後にpresentModalViewControllerを実行していたためです。

0
Nate Potter