Pergunta

Solução: Ao tentar recriar este bug em um projeto fresco para enviar para a Apple, eu descobri que ele é específico para iPhone OS 2.1, e compilando para 2.2 corrige o problema. Stephen, obrigado pela sua ajuda; Eu vou estar aceitando sua resposta, uma vez que teria funcionado se o bug ainda existia ou eu não estava disposta a compilar para 2.2.


Eu tenho um aplicativo que está mudando radicalmente seu esquema de banco de dados de uma forma que me obriga a transformar registros de estilo antigo para aqueles novo estilo no código. Como os usuários podem armazenar uma grande quantidade de dados neste aplicativo, eu estou tentando exibir um controlador de vista modal com uma barra de progresso enquanto os portos os dados mais (ou seja, como a primeira coisa que o usuário vê). viewDidAppear: deste controlador de vista começa uma transação de banco de dados e, em seguida, começa uma discussão de fundo para fazer a portabilidade real, que por vezes usa performSelectorInMainThread:withObject:waitUntilDone: para contar o segmento de primeiro plano para atualizar a barra de progresso.

O problema é, viewDidAppear: está sendo chamado duas vezes. Notei isso porque que "iniciar uma transação" etapa falhar com uma mensagem de "banco de dados ocupado", mas definir um ponto de interrupção revela que ele é de fato chamado duas vezes, uma vez por -[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:], e novamente por -[UIViewController modalPresentTransitionDidComplete]. Esses nomes parecem ser métodos UIViewController privadas, então eu estou supondo que este seja um bug quadro, ou eu estou fazendo algo UIKit não está esperando que eu faça.

Dois trechos de código relevantes (algum código irrelevante foi resumido):

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

Assim, há algo que eu estou estragar aqui, ou eu deveria apresentar um relatório de bug com Apple?

Foi útil?

Solução

Eu vi isso em meu aplicativo também. Eu nunca consegui-lo totalmente confirmado, mas acho que isso é o que está acontecendo:

  1. vista Carga root
  2. Load vista modal
  3. OS envia vista parecia notificação para a vista no passo 1
  4. atuais controlador de vista, que neste caso passa a ser sua classe DatabaseController, pega
  5. OS envia o ponto de vista fez aparecer a notificação para a vista modal
  6. O controlador de vista atual recebe a notificação. Neste caso, é exatamente o mesmo controlador como última vez

No meu caso eu só repor o que aconteceu na primeira chamada para viewDidAppear:.

No seu caso duas opções vêm à mente: uma variável estática para controlar se você começou já a atualização; ou olhar para o parâmetro UIView* passou em antes de começar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top