2

Résolution: En essayant de recréer ce bogue dans un nouveau projet à soumettre à Apple, j'ai découvert qu'il est spécifique à iPhone OS 2.1, et la compilation de 2.2 corrige le problème. problème. Stephen, merci pour votre aide. Je vais accepter votre réponse, car cela aurait fonctionné si le bug existait encore ou que je ne voulais pas compiler pour 2.2.viewDidAppear: appelé deux fois sur le contrôleur de vue modale présenté au démarrage


J'ai une application qui est en train de changer radicalement son schéma de base de données d'une manière qui me demande de transformer des documents de style ancien à ceux nouveau style dans le code. Comme les utilisateurs peuvent stocker beaucoup de données dans cette application, j'essaie d'afficher un contrôleur de vue modale avec une barre de progression pendant qu'il transfère les données (c'est-à-dire comme la première chose que voit l'utilisateur). Le contrôleur de vue viewDidAppear: commence une transaction de base de données, puis démarre un thread d'arrière-plan pour effectuer le portage réel, qui utilise parfois performSelectorInMainThread:withObject:waitUntilDone: pour indiquer au thread de premier plan de mettre à jour la barre de progression. Le problème est viewDidAppear: est appelé deux fois. J'ai remarqué cela parce que l'étape "démarrer une transaction" échoue avec un message "base de données occupée", mais l'établissement d'un point d'arrêt révèle qu'il est en effet appelé deux fois une fois par -[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:], et de nouveau par -[UIViewController modalPresentTransitionDidComplete]. Ces noms semblent être des méthodes privées UIViewController, donc je suppose que c'est un bug de framework, ou que je fais quelque chose que UIKit ne m'attend pas.

Deux extraits de code pertinents (un code non pertinent a été résumée):

- (void)applicationDidFinishLaunching:(UIApplication *)application { 
    (register some default settings in NSUserDefaults) 

    // doing this early because trying to present a modal view controller 
    // before the view controller is visible seems to break it 
    [window addSubview:[self.navigationController view]]; 

    // this is the method that may present the modal view 
    [self.databaseController loadDatabaseWithViewController:self.navigationController]; 

    if(!self.databaseController.willUpgrade) { 
     [self restoreNavigationControllerState]; 
    } 
} 

Et de ma classe DatabaseController:

- (void)loadDatabaseWithViewController:(UIViewController*)viewController { 
    (open the new database) 

    (compute the path the old database would live at if it existed) 

    if([[NSFileManager defaultManager] fileExistsAtPath:oldDBPath]) { 
     (open the old database) 

     [viewController presentModalViewController:self animated:NO]; 
    } 
} 

Alors, est-il quelque chose que je vissant ici, ou devrais-je déposer un rapport de bug avec Apple?

Répondre

3

J'ai vu cela dans mon application aussi. Je ne me suis jamais complètement confirmé, mais je pense que c'est ce qui se passe:

  1. charge vue racine
  2. vue modal charge
  3. OS envoie vue ne semble notification pour la vue à l'étape 1
  4. Le current contrôleur de vue, qui dans ce cas se trouve être votre classe DatabaseController, le prend en charge
  5. OS envoie la vue est apparu notification pour la vue modale
  6. T Le contrôleur de vue actuel reçoit la notification. Dans ce cas, c'est exactement le même contrôleur que la dernière fois

Dans mon cas, je viens de réinitialiser ce qui s'est passé dans le premier appel à viewDidAppear:. Dans votre cas, deux options viennent à l'esprit: une variable statique pour savoir si vous avez déjà commencé la mise à jour; ou regardez le paramètre UIView* passé avant de commencer.

+0

Comme je l'ai noté ci-dessus, j'ai finalement découvert qu'il a été corrigé dans OS 2.2, mais merci pour votre suggestion. –

+0

Pas de problème. Super pour voir la "vraie" réponse! –

Questions connexes