2

我花了一天的时间在我的 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];
}

问题是:当我在 Release 配置(使用 -Os 进行编译器优化)中运行我的项目时,我在交换模型对象期间崩溃。崩溃来自尝试访问 Zombie 对象。我使用 Instruments 来追踪我的对象的保留/释放路径,并且进入这个方法,_currentModel 的引用计数为 1,正如预期的那样。但是,该行INEWSStoryModel *swapModel = _currentModel;不会导致在 _currentModel 上调用保留,因此下一次调用_currentModel = _comingModel;会导致引用计数下降到 0。然后,当swapModel超出范围时,会尝试另一个释放调用,并且程序崩溃。

在我看来,编译器优化似乎正在优化它不应该的保留调用。有没有其他人遇到过这种类型的问题?我可能做错了什么吗?如有必要,我可以从课堂上发布更多代码。

其他有趣的注意事项:如果我将 swapModel 变量设置为 __autoreleasing,则代码有效。另外,如果我在 swap 方法的末尾添加以下代码块,则代码可以工作:

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

该方法所做的只是调整 UIView 框架。我可以在方法的末尾添加不相关的代码并且让它不会创建僵尸,这一事实让我认为编译器优化不正确。有人有想法么?

4

0 回答 0