Ho bisogno di ridimensionare una grande immagine memorizzata localmente (contenuta in self.optionArray
) e quindi mostrarla in collectionView. Se lo mostro, iOS sta cercando di ridimensionare le immagini mentre scorrono rapidamente causando arresti anomali relativi alla memoria.UICollectionView Cell Immagine cambiando come appare con GCD
Nel codice riportato di seguito, collectionView scorrerà senza problemi, ma a volte se si scorre estremamente veloce, l'immagine scorretta verrà visualizzata e quindi modificata rispetto a quella corretta mentre lo scorrimento decelera. Perché non sta impostando il su nil
risolvendolo?
- (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: ho aggiunto un altro asincrone a cache di primo e nil e inizializzato il cell.image. Sto avendo lo stesso problema sullo scorrimento veloce iniziale verso il basso. Tuttavia, sul backup di scorrimento, ora è impeccabile.
ho aggiunto questo:
-(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;
Tutte le immagini sono locali, nessuna viene scaricata da un server. Questo cambia qualcuno dei tuoi consigli? – Eric
@Eric Ah, scusa se non l'ho notato. In tal caso, è improbabile che il mio secondo punto si manifesti (anche se teoricamente potrebbe). E il quarto punto è anche meno di un problema. Ma i punti uno e tre sono decisamente rilevanti e potresti notare un leggero miglioramento delle prestazioni rispetto al quarto punto se usi una cache. Ti inviterei a testare il tuo codice sul dispositivo più lento possibile, perché non vedrai alcuni di questi problemi sul simulatore o su un dispositivo più recente. – Rob
puoi dare un'occhiata alla mia modifica? – Eric