Domanda

Risoluzione: Durante il tentativo di ricreare questo bug in un nuovo progetto da inviare ad Apple, ho scoperto che è specifico per iPhone OS 2.1 e la compilazione per 2.2 risolve il problema. Stephen, grazie per il tuo aiuto; Accetterò la tua risposta poiché avrebbe funzionato se il bug esistesse ancora o non fossi disposto a compilare per 2.2.


Ho un'app che sta cambiando radicalmente il suo schema di database in un modo che mi richiede di trasformare i record vecchio stile in nuovi nel codice. Poiché gli utenti possono archiviare molti dati in questa app, sto cercando di visualizzare un controller di visualizzazione modale con una barra di avanzamento mentre esegue il porting dei dati (ovvero come la prima cosa che l'utente vede). Il viewDidAppear del controller di visualizzazione: avvia una transazione del database e quindi avvia un thread in background per eseguire il porting effettivo, che a volte utilizza performSelectorInMainThread: withObject: waitUntilDone: per dire al thread in primo piano di aggiorna la barra di avanzamento.

Il problema è che viewDidAppear: viene chiamato due volte. Ho notato questo perché "inizia una transazione" il passaggio fallisce con un "database occupato" messaggio, ma l'impostazione di un punto di interruzione rivela che viene effettivamente chiamato due volte, una volta con - [UIViewController viewDidMoveToWindow: shouldAppearOrDisappear:] , e di nuovo con - [UIViewController modalPresentTransitionDidComplete] . Quei nomi sembrano essere metodi UIViewController privati, quindi immagino che si tratti di un bug del framework, o sto facendo qualcosa che UIKit non si aspetta che io faccia.

Due estratti di codice pertinenti (è stato riassunto un codice irrilevante):

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

E dalla mia 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];
    }
}

Quindi, c'è qualcosa che sto rovinando qui, o dovrei presentare una segnalazione di bug con Apple?

È stato utile?

Soluzione

L'ho visto anche nella mia app. Non l'ho mai confermato del tutto, ma penso che sia quello che sta succedendo:

  1. Carica vista radice
  2. Carica vista modale
  3. La vista di invio del sistema operativo ha visualizzato una notifica per la vista nel passaggio 1
  4. Il controller di visualizzazione corrente , che in questo caso sembra essere la tua classe DatabaseController, lo prende
  5. Il sistema operativo invia la vista appariva notifica per la vista modale
  6. L'attuale controller di visualizzazione riceve la notifica. In questo caso è esattamente lo stesso controller dell'ultima volta

Nel mio caso ho appena resettato ciò che è accaduto nella prima chiamata a viewDidAppear: .

Nel tuo caso vengono in mente due opzioni: una variabile statica per tracciare se hai già avviato l'aggiornamento; oppure guarda il parametro UIView * passato prima di iniziare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top