我花了一天的时间在我的 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 框架。我可以在方法的末尾添加不相关的代码并且让它不会创建僵尸,这一事实让我认为编译器优化不正确。有人有想法么?