Я только что закончил отладку очень неприятной утечки UIViewController
, так что UIViewController не был отключен даже после вызова dismissViewControllerAnimated
.
Я отследил проблему до следующего блока кода:
self.dataSource.doNotAllowUpdates = YES;
[self.collectionView performBatchUpdates:^{
[self.collectionView reloadItemsAtIndexPaths:@[indexPath]];
} completion:^(BOOL finished) {
self.dataSource.doNotAllowUpdates = NO;
}];
В принципе, если я позвоню performBatchUpdates
, а затем немедленно вызовите dismissViewControllerAnimated
, UIViewController просочится, и метод dealloc
этого UIViewController
никогда не будет вызван. 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
- это переменная, которую я добавил, которая предотвращает любые обновления данных dataSource/collectionView во время выполнения вызова executeBatchUpdates.
Я искал для обсуждения в Интернете вопрос о том, следует ли использовать шаблон weakSelf/strongSelf в performBatchUpdates
, но не нашел ничего конкретного в этом вопросе.
Я рад, что мне удалось разобраться с этой ошибкой, но мне бы хотелось, чтобы более умный разработчик iOS объяснил мне такое поведение, которое я вижу.