2014-07-01 44 views
1

在我的應用程序。我在主線程上獲得了一堆圖像URL,如下所示:UICollectionViewController不斷從異步圖像加載重新排列自己

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [self populateCollection]; 
} 

- (void)populateCollection 
{ 
    NSDictionary *json = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfURL:[MTGJSONBridge JSONURLWithSetCode:@"LEA"]] 
                 options:kNilOptions 
                  error:nil]; 
    NSLog(@"Json: %@", json); 
    NSArray *cards = json[@"cards"]; 
    _URLs = [NSMutableArray arrayWithCapacity:cards.count]; 
    for (NSDictionary *card in cards) 
    { 
     NSURL *imageURL = [MTGJSONBridge URLWithSetCode:@"LEA" cardName:card[@"imageName"]]; 
     if (imageURL) 
      [_URLs addObject:imageURL]; 
    } 
} 

這使我在0.2秒內獲得約300個URL。然後,我嘗試以異步方式從每個URL加載圖片是這樣的:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *identifier = @"reuseIdentifier"; 
    MTGCardCollectionCell *cell = (MTGCardCollectionCell *)[collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath]; 

    NSURL *url = _URLs[indexPath.row]; 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     // No explicit autorelease pool needed here. 
     // The code runs in background, not strangling 
     // the main run loop. 
     UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]]; 
     dispatch_sync(dispatch_get_main_queue(), ^{ 
      // This will be called on the main thread, so that 
      // you can update the UI, for example. 
      cell.imageView.image = image; 
     }); 
    }); 
    return cell; 
} 

我也有這樣的:

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

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 
{ 
    return _URLs.count; 
} 

收集負荷真的很快,並異步太(我可以在事情加載滾動,並且我看到新的圖像彈出)。問題是,當我上下滾動時,即使在所有圖像加載之後,它仍然按照隨機順序重新排列:我將查看一個單元格,然後將它的圖像與另一個單元格切換沒有明顯的原因。這是爲什麼發生?

回答

0

,我發現了一個很簡單的解決辦法:

if (cell.imageView.image == nil) 
{ 
    NSURL *url = _URLs[indexPath.row]; 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     // No explicit autorelease pool needed here. 
     // The code runs in background, not strangling 
     // the main run loop. 
     UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]]; 
     dispatch_sync(dispatch_get_main_queue(), ^{ 
      // This will be called on the main thread, so that 
      // you can update the UI, for example. 
      cell.imageView.image = image; 
     }); 
    }); 
} 
else 
{ 
    NSLog(@"Cell image isn't nil"); 
} 

我所要做的就是檢查單元尚未加載。原來,每當一個單元格進入視圖時調用- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath方法。即使它只是在視圖中。