Pregunta

Resolución: Al intentar recrear este error en un nuevo proyecto para enviarlo a Apple, descubrí que es específico del iPhone OS 2.1, y compilar para 2.2 soluciona el problema. Stephen, gracias por tu ayuda; Aceptaré tu respuesta, ya que habría funcionado si el error aún existiera o no estuviera dispuesto a compilar para 2.2.


Tengo una aplicación que está cambiando radicalmente su esquema de base de datos de una manera que requiere que transforme los registros de estilo antiguo a los de estilo nuevo en el código. Dado que los usuarios pueden almacenar una gran cantidad de datos en esta aplicación, estoy tratando de mostrar un controlador de vista modal con una barra de progreso mientras transfiere los datos (es decir, como lo primero que ve el usuario). El viewDidAppear: de este controlador de vista comienza una transacción de base de datos y luego inicia un subproceso en segundo plano para realizar la transferencia real, que ocasionalmente usa performSelectorInMainThread: withObject: waitUntilDone: para indicarle al subproceso en primer plano actualizar la barra de progreso.

El problema es que viewDidAppear: se llama dos veces. Me di cuenta de esto porque eso "inicia una transacción" el paso falla con una "base de datos ocupada" mensaje, pero establecer un punto de interrupción revela que efectivamente se llama dos veces, una vez por - [UIViewController viewDidMoveToWindow: shouldAppearOrDisappear:] , y nuevamente por - [UIViewController modalPresentTransitionDidComplete] . Esos nombres parecen ser métodos privados de UIViewController, por lo que supongo que es un error del marco o estoy haciendo algo que UIKit no espera que haga.

Dos extractos de código relevantes (se ha resumido un código irrelevante):

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

Y desde mi clase 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];
    }
}

Entonces, ¿hay algo que estoy arruinando aquí, o debería presentar un informe de error con Apple?

¿Fue útil?

Solución

También vi esto en mi aplicación. Nunca lo confirme por completo, pero creo que esto es lo que está sucediendo:

  1. Cargar vista de raíz
  2. Cargar vista modal
  3. OS envía la vista apareció notificación para la vista en el paso 1
  4. El controlador de vista actual , que en este caso es su clase DatabaseController, lo recoge
  5. OS envía la vista apareció notificación de la vista modal
  6. El controlador de vista actual recibe la notificación. En este caso, es exactamente el mismo controlador que la última vez

En mi caso, simplemente restablecí lo que sucedió en la primera llamada a viewDidAppear: .

En su caso, se me ocurren dos opciones: una variable estática para rastrear si ya ha comenzado la actualización; o mire el parámetro UIView * pasado antes de comenzar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top