viewDidAppear: дважды вызывается на контроллере модального представления, представленном при запуске

StackOverflow https://stackoverflow.com/questions/619269

Вопрос

Разрешение . Пытаясь воссоздать эту ошибку в новом проекте для отправки в Apple, я обнаружил, что он относится к iPhone OS 2.1, и компиляция для 2.2 устраняет проблему. Стивен, спасибо за вашу помощь; Я приму ваш ответ, так как он сработал бы, если бы ошибка все еще существовала или я не хотел компилировать для 2.2.

<Ч>

У меня есть приложение, которое радикально меняет свою схему базы данных таким образом, что мне требуется преобразовать записи старого стиля в записи нового стиля в коде. Так как пользователи могут хранить много данных в этом приложении, я пытаюсь отобразить контроллер модального представления с индикатором выполнения, в то время как он переносит данные (то есть, как первое, что видит пользователь). viewDidAppear: этого контроллера представления начинает транзакцию базы данных, а затем запускает фоновый поток, чтобы выполнить фактическое портирование, которое иногда использует executeSelectorInMainThread: withObject: waitUntilDone: , чтобы сообщить приоритетному потоку обновить индикатор выполнения.

Проблема в том, что viewDidAppear: вызывается дважды. Я заметил это, потому что это «начать транзакцию» шаг завершается неудачно с "база данных занята" сообщение, но установка точки останова показывает, что она действительно вызывается два раза - один раз - [UIViewController viewDidMoveToWindow: shouldAppearOrDisappear:] , а затем снова - [UIViewController modalPresentTransitionDidComplete] , Эти имена, по-видимому, являются частными методами UIViewController, поэтому я предполагаю, что это либо ошибка фреймворка, либо я делаю что-то, что UIKit не ожидает от меня.

Две соответствующие выдержки из кода (некоторые нерелевантные коды были обобщены):

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

И из моего класса 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];
    }
}

Итак, есть что-то, что я здесь напортачу, или я должен отправить отчет об ошибке в Apple?

Это было полезно?

Решение

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

<Ол>
  • Загрузить корневой вид
  • Загрузить модальное представление
  • ОС отправляет представление. Появилось уведомление для представления на шаге 1
  • Контроллер представления current , который в данном случае является вашим классом DatabaseController, забирает его
  • ОС отправляет представление, появилось уведомление для модального представления
  • Текущий контроллер представления получает уведомление. В этом случае это тот же контроллер, что и в прошлый раз.
  • В моем случае я просто сбросил то, что произошло при первом вызове, на viewDidAppear: .

    В вашем случае на ум приходят два варианта: статическая переменная для отслеживания того, начали ли вы уже обновление; или посмотрите параметр UIView * , переданный перед запуском.

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top