iOS:numberOfSectionsInCollectionView消息发送到解除分配的实例

时间:2014-02-12 10:36:51

标签: ios crash uicollectionview dispatch-async

我有这个代码来管理集合视图

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return  1;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return [images count];
}

- (PhotoCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{

    PhotoCell *cell = [gridPhoto dequeueReusableCellWithReuseIdentifier:@"photocell" forIndexPath:indexPath];

    NSMutableDictionary *record = [images objectAtIndex:[indexPath row]];
    if ([record valueForKey:@"actualImage"]) {
        [cell.image setImage:[record valueForKey:@"actualImage"]];
        [cell.activity stopAnimating];
    } else {
        dispatch_async(imageQueue_, ^{
            NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[record objectForKey:@"url"]]];
            dispatch_async(dispatch_get_main_queue(), ^{
                [record setValue:[UIImage imageWithData:imageData] forKey:@"actualImage"];
                [collectionView reloadItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]];
            });
        });
    }

    return cell;
}

如果imageQueue_完成其工作并填充整个collectionview,它可以正常工作;当我从我的视图中退出呼叫后退时,我遇到了问题

- (IBAction)back:(id)sender{
    [self.navigationController popViewControllerAnimated:YES];
}

在这种情况下,如果集合视图不是完整的图像填充,我在执行后退操作时会出现此错误:

[PhotoGalleryViewController numberOfSectionsInCollectionView:]: message sent to deallocated instance 0x1590aab0

问题出在哪里?

1 个答案:

答案 0 :(得分:1)

弹出视图控制器时,下载仍在进行中。因此,当执行异步回调时,[collectionView reloadItemsAtIndexPaths...]会在不再存在的collectionView上调用。

您应该在回调版块的第一行检查collectionView != nil,如果它是零,则只检查return;

dispatch_async(dispatch_get_main_queue(), ^{
    if (collectionView == nil)
        return;

    [record setValue:[UIImage imageWithData:imageData] forKey:@"actualImage"];
    [collectionView reloadItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]];
});