dismissModalViewControllerAnimated: (и dismissViewControllerAnimated) сбой в iOS 5 - PullRequest
9 голосов
/ 19 октября 2011

Я не могу найти никакого логического объяснения, но факт остается фактом: в iOS 5 (xCode 4.2), если я представлюModalView: * animated: YES, я могу вызвать dismissModalViewAnimated: * штраф, но если я вызову presentModalView: * animated: NO, затем вызывается метод dismiss, сбой. (Это работает так же, если я использую новый presentViewController: animated: завершение: + dismissViewControllerAnimated :). Я собираюсь попытаться обойти это сейчас (я не хочу, чтобы презентация была анимированной) и сообщить об ошибке в Apple, но я уже давно бьюсь над этим. Любые и все предложения приветствуются. Не так уж много на iOS 5, поэтому, пожалуйста, помогите, если можете. Пример кода, который не дает сбоя в iOS 4 или iOS 5:

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

Это приведет к сбою в iOS 5 с EXC_BAD_ACCESS при вызове dismiss:

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 приложение: 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];  
}

В контроллере входа в систему:

- (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
}    

Ответы [ 2 ]

4 голосов
/ 19 октября 2011

В 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]
    }
}

Любопытная обратная связь:) ....

2 голосов
/ 12 января 2012

Я добавлю свои 2 цента: у меня был ImagePickerController и он работал, только когда я не отпускал сборщик вручную (IOS 5 SDK).

Итак. для вашего случая я мог бы предложить такой обходной путь: 1. удалить строку - [релиз loginController]; 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

Удачи:)

P.S. Я только что написал это, так что это просто идея, как обмануть это. Somebosy может исправить меня ... хотя в любом случае это сработало для меня.

...