我刚刚修复了一个非常棘手的UIViewController
泄漏问题,即使调用dismissViewControllerAnimated
后也不能释放UIViewController
。
我将问题追踪到以下代码块:
self.dataSource.doNotAllowUpdates = YES;
[self.collectionView performBatchUpdates:^{
[self.collectionView reloadItemsAtIndexPaths:@[indexPath]];
} completion:^(BOOL finished) {
self.dataSource.doNotAllowUpdates = NO;
}];
基本上,如果我调用performBatchUpdates
,然后立即调用dismissViewControllerAnimated
,UIViewController 就会泄漏,这个 UIViewController 的 dealloc
方法永远不会被调用,UIViewController 会一直存在。
有人可以解释一下这种行为吗?我认为 performBatchUpdates
在某个时间间隔内运行,比如 500 毫秒,所以我会认为在该时间间隔之后,它会调用这些方法,然后触发 dealloc。
修复方法似乎是这样的:
self.dataSource.doNotAllowUpdates = YES;
__weak __typeof(self)weakSelf = self;
[self.collectionView performBatchUpdates:^{
__strong __typeof(weakSelf)strongSelf = weakSelf;
if (strongSelf) {
[strongSelf.collectionView reloadItemsAtIndexPaths:@[indexPath]];
}
} completion:^(BOOL finished) {
__strong __typeof(weakSelf)strongSelf = weakSelf;
if (strongSelf) {
strongSelf.dataSource.doNotAllowUpdates = NO;
}
}];
请注意,BOOL
成员变量doNotAllowUpdates
是我添加的变量,它可以防止在执行performBatchUpdates
时进行任何种类的数据源/集合视图更新。我搜索了一下关于是否应在
performBatchUpdates
中使用weakSelf/strongSelf模式的在线讨论,但没有找到具体针对这个问题的内容。我很高兴能够找到此错误的根本原因,但我希望有更聪明的iOS开发人员能解释一下我看到的这种行为。