问题
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
}
来源:https://stackoverflow.com/questions/13309125/ios-showing-image-from-alasset-in-uitableview