9

論理的な説明は見つかりませんが、iOS 5(xCode 4.2)では、presentModalView:*アニメーション:YESの場合、dismissModalViewAnimated:*を正常に呼び出すことができますが、presentModalView:*アニメーション:NOを呼び出すと、事実は変わりません。 、次にdismissメソッドを呼び出すとクラッシュします。(これは、新しいpresentViewController:animated:completion:+ dismissViewControllerAnimated:を使用した場合も同じように機能します)。私は今のところこれを回避して(プレゼンテーションをアニメーション化したくない)、Appleにバグを報告するつもりですが、私はしばらくの間これに頭を悩ませてきました。ありとあらゆる提案を歓迎します。iOS 5にはあまりありませんので、できれば助けてください。iOS4またはiOS5でクラッシュしないサンプルコード:

LoginController *loginController = [[LoginController alloc] initWithNibName:@"LoginControllerGG" bundle:nil];
[self presentModalViewController:loginController animated:YES];
[loginController release];
...
[self dismissModalViewControllerAnimated:YES];

これは、iOS5でEXC_BAD_ACCESSを使用して却下呼び出しでクラッシュします。

LoginController *loginController = [[LoginController alloc]    initWithNibName:@"LoginControllerGG" bundle:nil];
[self presentModalViewController:loginController animated:NO];
[loginController release];
...
[self dismissModalViewControllerAnimated:YES]; //crashes with EXC_BAD _ACCESS

注:loginController内に、viewDidLoadで発生するアニメーションがあります。それを取り除くことで何かが変わるかどうかを見に行くが、私はできるだけ早く解決策が必要なので、これをそこに出したかった。


[編集]完全なコードフロー...AppDelegateで、application:didFinishLaunchingWithOptions:

if (!loggedIn)  [myViewController showLoginPanel];

myViewControllerの場合:

- (void)showLoginPanel {    
    LoginController *loginController = [[LoginController alloc] initWithNibName:@"LoginControllerGG" bundle:nil];
    if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]) {
        [self presentViewController:loginController animated:NO completion:nil];
    } else {
        [self presentModalViewController:loginController animated:NO]; //iOS 4 works fine with or without animation   
    } 
    [loginController release];  
}

loginControllerの場合:

- (IBAction)closeLoginWindow {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"CloseLoginWindow" object:nil];
}   //doing it this way because calling on the self.parentViewController doesn't work

myViewControllerに戻ります。

- (void) viewDidLoad
    ...
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(closeLoginWindow) name:@"CloseLoginWindow" object:nil];
    ...

- (void)closeLoginWindow {
    if ([self respondsToSelector:@selector(dismissViewControllerAnimated:completion:)]) {
        [self dismissViewControllerAnimated:YES completion:nil];    //iOS 5 crashes only if presentation was not animated
    } else [self dismissModalViewControllerAnimated:YES];    //deleting the previous condition, iOS 5 still crashes if presentation was not animated
}    
4

2 に答える 2

4

iOS5 では、ライフサイクルの管理が何らかの形で変更されましたが、その問題について詳しく説明することはできません。とにかく、修正は、そのワークフローを applicationDidFinishLaunchingWithOptions から applicationDidBecomeActive に延期することです。applicationDidFinishLaunchingWithOptions の呼び出し時に何かが正しく初期化されていないようです。

- (void)applicationDidFinishLaunchingWithOptions:... {    
    // in order to do this only at launching, but not on every activation 
    // Declaration as property for example
    applicationDidLaunch = YES;
}

- (void) applicationDidBecomeActive:(UIApplication *)application {
    if (applicationDidLaunch) {
        applicationDidLaunch = NO;
        [Start your login Workflow with modal view presenting here]
    }
}

あなたのフィードバックに興味があります:)...

于 2011-10-19T15:32:28.840 に答える
2

私は2セントを追加します:私はImagePickerControllerを持っていて、ピッカーを手動で解放しなかった場合にのみ(IOS 5 SDK)、その却下が機能しました。

そう。あなたの場合、私はそのような回避策を提供できます: 1. 行を削除 - [loginController release]; 2. メモリ リークを防ぐには、loginController をプロパティとして現在のコントローラーに追加し、現在のコントローラーの dealloc() でのみ解放します。

@interface myViewController : UIViewController 

@property (nonatomic, retain) LoginController *loginController;

@end

...

@implementation myViewController

- (void)showLoginPanel {    
    self.loginController = [[LoginController alloc] initWithNibName:@"LoginControllerGG" bundle:nil];
     // ... something goes here  
}

-(IBAction)loginClose() 
{
    // this should close all windows as far as you call it from current (main) controller
    [self dismissModalViewControllerAnimated:YES]; 
    // ... then anything you want EXCEPT [loginController release];
}

-(void)dealloc() 
{
    [loginController release];
}

@end

幸運を :)

PS私はこれを書いたばかりなので、それをだます方法にすぎません。誰かが私を修正するかもしれません...とにかくそれは私にとってはうまくいきました。

于 2012-01-11T23:44:03.603 に答える