我需要調整大量本地存儲的圖像(包含在self.optionArray
),然後顯示它在的CollectionView。如果我只是展示它,iOS會嘗試調整圖像的大小,因爲我快速滾動導致與內存相關的崩潰。UICollectionView細胞圖像改變,因爲它進入視野與GCD
在下面的代碼,所述的CollectionView將平穩滾動,但有時,如果我滾動速度極快,會有不正確的圖像顯示,然後改變到正確的一個作爲滾動減速。爲什麼不將cell.cellImage.image
設置爲nil
修復此問題?
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CustomTabBarCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CustomTabBarCell" forIndexPath:indexPath];
cell.cellImage.image = nil;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
cell.cellImage.image = nil;
UIImage *test = [self.optionArray objectAtIndex:indexPath.row];
UIImage *localImage2 = [self imageWithImage:test scaledToSize:CGSizeMake(test.size.width/5, test.size.height/5)];
dispatch_sync(dispatch_get_main_queue(), ^{
cell.cellImage.image = localImage2
cell.cellTextLabel.text = @"";
[cell setNeedsLayout];
});
});
}
return cell;
}
- (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
編輯: 我又增加了異步緩存第一和零和初始化cell.image。我在初始快速向下滾動時遇到了同樣的問題。然而,在翻卷的時候,它現在完美無瑕。
我加了這一點:
-(void)createDictionary
{
for (UIImage *test in self.optionArray) {
UIImage *shownImage = [self imageWithImage:test scaledToSize:CGSizeMake(test.size.width/5, test.size.height/5)];
[localImageDict setObject:shownImage forKey:[NSNumber numberWithInt:[self.optionArray indexOfObject:test]]];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
if (!localImageDict) {
localImageDict = [[NSMutableDictionary alloc]initWithCapacity:self.optionArray.count];
}
else {
[localImageDict removeAllObjects];
}
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
[self createDictionary];
});
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CustomTabBarCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CustomTabBarCell" forIndexPath:indexPath];
cell.cellImage.image = nil;
cell.cellImage.image = [[UIImage alloc]init];
if ([localImageDict objectForKey:[NSNumber numberWithInt:indexPath.row]]) {
cell.cellImage.image = [localImageDict objectForKey:[NSNumber numberWithInt:indexPath.row]];
cell.cellTextLabel.text = @"";
}
else {
cell.cellImage.image = nil;
cell.cellImage.image = [[UIImage alloc]init];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
UIImage *test = [self.optionArray objectAtIndex:indexPath.row];
UIImage *shownImage = [self imageWithImage:test scaledToSize:CGSizeMake(test.size.width/5, test.size.height/5)];
[localImageDict setObject:shownImage forKey:[NSNumber numberWithInt:indexPath.row]];
dispatch_sync(dispatch_get_main_queue(), ^{
cell.cellImage.image = shownImage;
cell.cellTextLabel.text = @"";
[cell setNeedsLayout];
});
});
}
}
return cell;
所有的圖像都是本地的,沒有一個是從服務器上下載的。這是否會改變您的任何建議? – Eric
@Eric啊,對不起,我沒有注意到。在這種情況下,我的第二點不可能表現出來(儘管理論上可以)。第四點也不是什麼問題。但是,第一點和第三點絕對相關,如果您使用緩存,則可能會看到第四點的性能略有改善。我鼓勵你在最慢的設備上測試你的代碼,因爲你不會在模擬器或更新的設備上看到這些問題。 – Rob
你可以看看我的編輯? – Eric