iOS showing Image from ALAsset in UITableView

2020-08-04 10:08发布

问题:

I have a db where items are stored. These items can be different kinds of type like text, videos and images. When the View is loaded I fetch these items from the DB and I show them in a UITableView. The problem I am facing is related to show the images in the table view. Basically in the DB I store the ALAsset link related to the picture and from it I try to get its image using this code:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

 //...Other Code

  else if ([object isMemberOfClass:[Picture class]]){

            //Get a reusable cell
            cell = [tableView dequeueReusableCellWithIdentifier:@"pictureCellIdentifier"];

            // [self performSelectorInBackground:@selector(performAsset:) withObject:dict];

            ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
            {
                ALAssetRepresentation *rep = [myasset defaultRepresentation];
                CGImageRef iref = [rep fullResolutionImage];
                if (iref) {
                    ((PictureViewCell *)cell).placeHolderImageView.hidden = YES;
                    ((PictureViewCell *)cell).pictureImageView.image =  [UIImage imageWithCGImage:[rep fullResolutionImage]  scale:[rep scale] orientation:(UIImageOrientation)[rep orientation]];

                }
            };


            ALAssetsLibraryAccessFailureBlock failureblock  = ^(NSError *myerror)
            {
                 [Utility showAlertViewWithTitle:@"Location Error" message:@"You must activate Location Services to access the photo" cancelButtonTitle:@"Dismiss"];

            };

            ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
            [assetslibrary assetForURL:[NSURL URLWithString:((Picture *)objectInArray).imagePath]
                           resultBlock:resultblock
                          failureBlock:failureblock];

         //Set the background for the cell
            cell.backgroundView = iv;

        }

 //...Other code

}

The problem is that when you slide through the cell the method gets called and the app is really slow. So I guess there are better ways to achieve what I'm trying to do. I also tried to perform that code using performselectorInBackground:. Performance seem better but It takes more time to fetch the image.

Any helps would be really appreciated.

Thanks!

回答1:

There are a few things that can be improved here.

The first is as you figured out: Do the loading of the assets in background thread and then add the image to the cell when it is ready on the main thread. Next, you are creating an object of ALAssetsLibrary for every cell that you show. Ideally, an app should have just one object of ALAssetsLibrary that you retain as long as you need it. Create a ALAssetsLibrary the first time you need and then reuse it.

- (ALAssetsLibrary *)defaultAssetsLibrary {
    if (_library == nil) {
        _library = [[ALAssetsLibrary alloc] init];
    }
    return _library;
}

And the last, you are using the fullResolutionImage in a tableview cell. If you really just need to display the image, a thumbnailImage or at least a fullScreenImage should be good enough.

- (void) loadImage:(NSNumber *)indexPath url:(NSURL*)url
{
    int index = [indexPath intValue];

    ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
    {
        CGImageRef iref = [[myasset defaultRepresentation] fullScreenImage];
        if (iref) {
            // TODO: Create a dictionary with UIImage and cell indexPath

            // Show the image on main thread
            [self performSelectorOnMainThread:@selector(imageReady:) withObject:result waitUntilDone:NO];
        }
    };
    ALAssetsLibraryAccessFailureBlock failureblock  = ^(NSError *myerror)
    {
         [Utility showAlertViewWithTitle:@"Location Error" message:@"You must activate Location Services to access the photo" cancelButtonTitle:@"Dismiss"];

    };

    [[self defaultAssetsLibrary] assetForURL:url
                   resultBlock:resultblock
                  failureBlock:failureblock];
}

-(void) imageReady:(NSDictionary *) result
{
    // Get the cell using index path

    // Show the image in the cell
}