Potrzebuję zmienić rozmiar dużego obrazu zapisanego lokalnie (zawartego w self.optionArray
), a następnie wyświetlić go w kolekcji view. Jeśli po prostu to pokażę, iOS próbuje zmienić rozmiar obrazów podczas szybkiego przewijania, powodując awarie pamięci.UICollectionView Cell Zmiana obrazu w widoku z GCD
W poniższym kodzie kolekcjaView będzie płynnie przewijana, ale czasami, gdy przewijam bardzo szybko, pojawi się niepoprawny obraz, który pokazuje, a następnie zmienia się na prawidłowy, gdy przewijanie maleje. Dlaczego nie ustawiasz tego ustawienia na cell.cellImage.image
do 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;
}
EDIT: dodałem kolejną asynchronicznie do pamięci podręcznej pierwszego i nil i zainicjowaniu cell.image. Mam ten sam problem przy początkowym przewijaniu w dół. Jednak na przewinięciu kopii zapasowej jest teraz bez skazy.
dodałem to:
-(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;
Wszystkie obrazy są lokalne, żadne nie są pobierane z serwera. Czy to zmienia jakąś twoją rekomendację? – Eric
@Eric Ah, przepraszam, że tego nie zauważyłem. W takim przypadku mój drugi punkt raczej się nie ujawni (choć teoretycznie mógłby). Czwarty punkt nie jest też problemem. Ale punkty 1 i 3 są zdecydowanie trafne i możesz zauważyć niewielką poprawę wydajności czwartego punktu, jeśli korzystasz z pamięci podręcznej. Zachęcam Cię do przetestowania kodu na najwolniejszym możliwym urządzeniu, ponieważ niektóre z tych problemów nie pojawią się na symulatorze lub nowszym urządzeniu. – Rob
Czy możesz obejrzeć moją edycję? – Eric