将图像异步加载到UICollectionView?

Nav*_*avi 7 asynchronous objective-c ios uicollectionview

如何将图像UICollectionview异步加载?内幕方法如下?

- (PSTCollectionViewCell *)collectionView:(PSTCollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

 bookImage = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@", docPath, [[preview objectAtIndex:indexPath.row] lastPathComponent]]];
 [[cell grid_image] setImage:bookImage];

}
Run Code Online (Sandbox Code Playgroud)

viewdidload()中我使用以下异步调用将图像加载到"预览"NSMutablearray

 dispatch_queue_t imageLoadQueue = dispatch_queue_create("com.GMM.assamkar", NULL);

dispatch_async(imageLoadQueue, ^{
    //Wait for 5 seconds...
    usleep(1000000);
    docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];


    for(int k=0; k <[allImage count] ;k++){


        imgURL = [allImage objectAtIndex:k];
        [imagePreview addObject:imgURL];
        imgData=[NSData dataWithContentsOfURL:[NSURL URLWithString:imgURL]];


        [imgData writeToFile:[NSString stringWithFormat:@"%@/%@", docPath, [allImage lastPathComponent]] atomically:YES];

    }

    [[self collectionView] reloadData];


});
Run Code Online (Sandbox Code Playgroud)

请帮帮我..现在花了太多时间装货......

Jon*_*auz 9

试着回答你的主要问题"如何将图像UICollectionview异步加载?"

我建议在这里提供" Natasha Murashev " 提供的解决方案,这对我很有用,而且很简单.

如果imgURL = [allImage objectAtIndex:k];allImage属性中存在URL数组,则更新您的collectionView:cellForItemAtIndexPath:方法,如下所示:

- (PSTCollectionViewCell *)collectionView:(PSTCollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    NSURL *url = [NSURL URLWithString:[allImage objectAtIndex:indexPath]];

    [self downloadImageWithURL:url completionBlock:^(BOOL succeeded, NSData *data) {
        if (succeeded) {
            cell.grid_image.image = [[UIImage alloc] initWithData:data];
        }
    }];
}
Run Code Online (Sandbox Code Playgroud)

downloadImageWithURL:completionBlock:为您的类添加方法,该方法将异步加载图像并在成功下载图像时自动更新CollectionView中的单元格.

- (void)downloadImageWithURL:(NSURL *)url completionBlock:(void (^)(BOOL succeeded, NSData *data))completionBlock
{
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
        if (!error) {
            completionBlock(YES, data);
        } else {
            completionBlock(NO, nil);
        }
    }];
}
Run Code Online (Sandbox Code Playgroud)

我看到你试图在视图出现之前预先加载图像,所以也许我的解决方案不是你的意思,但是从你的问题来看很难说.不管如何,你也可以用这个来达到你想要的效果.

Swift中的Swift 2.2 解决方案.

public typealias ImageFetchCompletionClosure = (image: UIImage?, error: NSError?, imageURL: NSURL?) -> Void

extension String {
   func fetchImage(completionHandler: (image: UIImage?, error: NSError?, imageURL: NSURL?) -> Void) {
        if let imageURL = NSURL(string: self) {
            NSURLSession.sharedSession().dataTaskWithURL(imageURL) { data, response, error in
                guard
                    let httpURLResponse = response as? NSHTTPURLResponse where httpURLResponse.statusCode == 200,
                    let mimeType = response?.MIMEType where mimeType.hasPrefix("image"),
                    let data = data where error == nil,
                    let image = UIImage(data: data)
                    else {
                        if error != nil {
                            completionHandler(image: nil, error: error, imageURL: imageURL)
                        }
                        return
                }
                dispatch_sync(dispatch_get_main_queue()) { () -> Void in
                    completionHandler(image: image, error: nil, imageURL: imageURL)
                }
            }.resume()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用范例:

    "url_string".fetchImage { (image, error, imageURL) in
        // handle different results, either image was downloaded or error received
    }
Run Code Online (Sandbox Code Playgroud)


use*_*925 0

此代码创建串行队列:

dispatch_queue_t imageLoadQueue = dispatch_queue_create("com.GMM.assamkar", NULL);
Run Code Online (Sandbox Code Playgroud)

因此,队列中的每个任务都在同一线程中连续执行。因此,您的单个工作线程由每个加载任务的睡眠来维持,这会减慢所有加载过程。

通过使用类似的东西来使用异步 CONCURRENT 队列:

dispatch_queue_t imageLoadQueue = dispatch_queue_create("com.GMM.assamkar", DISPATCH_QUEUE_CONCURRENT);
Run Code Online (Sandbox Code Playgroud)