2

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


У меня есть приложение, которое коренным образом меняет свою схему базы данных таким образом, что требует от меня, чтобы преобразовать записи старого стиля в них нового стиля в коде. Поскольку пользователи могут хранить много данных в этом приложении, я пытаюсь отобразить контроллер модального представления с индикатором выполнения, пока он переносит данные (т. Е. Как первое, что видит пользователь). Контроллер viewDidAppear: этого вида управления начинает транзакцию базы данных и затем запускает фоновый поток для фактического портирования, который иногда использует performSelectorInMainThread: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?

ответ

3

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

  1. вид корневой нагрузки
  2. вид нагрузки модальный
  3. OS отправляет мнение было появиться уведомление о представлении на шаге 1
  4. текущий диспетчер представлений, который в этом случае является вашим классом DatabaseController, выбирает его
  5. OS отправляет уведомление о появлении уведомления для модального просмотра
  6. T его текущий контроллер просмотра получает уведомление. В этом случае это тот же самый контроллер, что и в последний раз

В моем случае я просто сбросил то, что произошло при первом вызове viewDidAppear:.

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

+0

Как я уже отмечал выше, я в конце концов обнаружил, что он был исправлен в OS 2.2, но спасибо за ваше предложение. –

+0

Нет проблем. Замечательно видеть «настоящий» ответ! –