NSZombie создан с -Os и автоматическим подсчетом ссылок в разработке iOS 5 - PullRequest
2 голосов
/ 10 февраля 2012

Я провел день, работая над странной ошибкой в ​​своем приложении для iOS 5 для iPad, и мне было интересно, есть ли у кого-нибудь какая-нибудь информация.

Вот общая настройка: есть подкласс UIViewController StoryViewChildController, который имеет две переменные-члены: _currentModel и _comingModel. В StoryViewChildController есть метод, который вызывает [[INEWSStoryModel alloc] init] и возвращает созданный результирующий объект. Во время viewDidLoad у меня есть следующий блок кода. Обратите внимание, что это не дословно скопировано из кода - это более сложно - но я пытаюсь подвести итог:

_currentModel = [self createModel];
_comingModel = [self createModel];

Затем, в какой-то момент, я должен иметь возможность поменять местами _currentModel и _comingModel вместе с другими объектами. Вот метод обмена, дословно из моего кода:

- (void)swapComingPageAndCurrentPage {

  [_swapLock lock];
  //Swap story views
  IPCStoryView *swapPage = _currentPage;
  _currentPage = _comingPage;
  _comingPage = swapPage;

  //Swap models
  INEWSStoryModel *swapModel = _currentModel;
  _currentModel = _comingModel;
  _comingModel = swapModel;

  //Swap players
  PlayerController *swapPlayer = _currentPlayerController;
  _currentPlayerController = _comingPlayerController;
  _comingPlayerController = swapPlayer;

  // clear out the content of the old view
  [_comingPage resetStoryView];
  [_comingPlayerController resetPlayer];
  _comingPlayerController.view.alpha = 0.0; 

  _currentPageURI = _lastRequestedStory;
  [_swapLock unlock];
}

Проблема в том, что когда я запускаю свой проект в конфигурации выпуска (которая использует -O для оптимизации компилятора), происходит сбой во время обмена объектами модели. Авария происходит из-за попытки получить доступ к объекту Zombie. Я использовал Инструменты, чтобы отследить путь сохранения / освобождения моих объектов, и, входя в этот метод, _currentModel имеет счетчик ссылок 1, как и ожидалось. Однако строка INEWSStoryModel *swapModel = _currentModel; НЕ приводит к вызову сохранения в _currentModel, поэтому при следующем вызове _currentModel = _comingModel; число ссылок уменьшается до 0. Затем, когда swapModel выходит из области действия, другой вызов освобождения попытался, и программа вылетает.

Мне почти кажется, что оптимизация компилятора оптимизирует сохранение вызовов, которые не следует делать. У кого-нибудь еще была такая проблема? Могу ли я сделать что-то еще не так? При необходимости могу выложить больше кода из класса.

Другие интересные примечания: если я установлю переменную swapModel как __autoreleasing, код будет работать. Кроме того, если я добавляю следующий блок кода в конце метода подкачки, код работает:

_comingPage.cueView.frame = [_comingPage adjustCueViewFrame:_comingPage.cueView.frame
                              ForVideoShowing: NO
                                inOrientation:_currentOrientation];

Все, что делает этот метод, это настраивает фрейм UIView. Тот факт, что я могу добавить несвязанный код в конец метода и не создавать зомби, заставляет меня думать, что компилятор неправильно оптимизирует. У кого-нибудь есть идеи?

...