Terminated due to Memory Pressure By using AssetsLibrary.framework - alassetslibrary

I am using AssetsLibrary.framework for fetching images from device gallery.I successfully fetched all images from gallery and displayed on my table view.Problem comes when I scroll up and down many times , I receive a memory issue warning getting printed on console and after some time it gets crashed saying CRASHED DUE TO MEMORY PRESSURE.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
ALAsset *asset = [self.images objectAtIndex:indexPath.row];
ALAssetRepresentation *representation = [asset defaultRepresentation];
image=[UIImage imageWithCGImage:[representation fullResolutionImage]];
[selectedAllImages addObject:image];
url = [representation url];
NSURL *imageURL=url;
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
ALAssetRepresentation *representation = [myasset defaultRepresentation];
fileName = [representation filename];
cell.cellLabel.text=fileName;
};
assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:imageURL
resultBlock:resultblock
failureBlock:nil];
[cell.cellImageView setImage:[UIImage imageWithCGImage:[asset thumbnail]]];
return cell;
}
So I need help where the mistake is?Thanks

ALAssetRepresentation *representation = [asset defaultRepresentation];
image=[UIImage imageWithCGImage:[representation fullResolutionImage]];
[selectedAllImages addObject:image];
url = [representation url];
Why do you getting fullResolutionImage in cellForRowAtIndexPath method? And putting into selectedAllImages array.. it seems like selectedAllImages array fills by fullresolutionimages infinity (during scrolling).
assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:imageURL
resultBlock:resultblock
failureBlock:nil];
Why you create assetslibrary and request for same asset (which have same url)?
I think you should simplify your 'cellForRowAtIndexPath' method, to be more lightweight during scrolling. Something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
ALAsset *asset = [self.images objectAtIndex:indexPath.row];
ALAssetRepresentation *representation = [asset defaultRepresentation];
cell.cellLabel.text = [representation filename];
cell.cellImageView.image = [UIImage imageWithCGImage:[asset thumbnail]];
return cell;
}

The images you're loading from the asset library are going to be large. If your trying to load many of them on a table view then you will quickly run out of memory. The usual practice is to create scaled images from the larger images, which use a lot less memory.

Related

Images load table is very slow [duplicate]

This question already has answers here:
UITableview with images scroll very slow
(6 answers)
Closed 9 years ago.
i am getting data from server that contains some images i get properly from url and set it to the tablview cell correctly done.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
AppDelegate * delegate=(AppDelegate *)[[UIApplication sharedApplication]delegate];
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text=[delegate.firstArray objectAtIndex:indexPath.row];
NSLog(#"%#",delegate.thirdArray);
url = [NSURL URLWithString:[NSString stringWithFormat:#"%#",[delegate.thirdArray objectAtIndex:indexPath.row]]];
data = [[NSData alloc]initWithContentsOfURL:url];
UIImage * img=[UIImage imageWithData:data];
cell.imageView.image=img;
return cell;
}
in delegate.thirdArray contais this url
"http://awe.com/app/images/can.png",
"http://awe.com/app/images/card.png",
"http://awe.com/app/images/tp.png",
"http://awe.com/app/images/tricks.png"
images load properly but it will take some time to load that image and scroll the tableview it will very slow i want it to be fast how may i do this.
Load your images using [NSURLConnection sendAsynchronousRequest:queue:completionHandler: then use NSCache to prevent downloading the same image again and again.
As suggested by many developers go for SDWebimage and it does include the above strategy to download the images files .You can load as many images you want and the same URL won't be downloaded several times as per the author of the code
Example on [NSURLConnection sendAsynchronousRequest:queue:completionHandler:
NSURL *url = [NSURL URLWithString:#"your_URL"];
NSURLRequest *myUrlRequest = [NSURLRequest requestWithURL:url];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest: myUrlRequest queue: queue completionHandler: ^ (NSURLResponse *response, NSData *data, NSError *error)
{
if ([data length] > 0 && error == nil)
//doSomething With The data
else if (error != nil && error.code == ERROR_CODE_TIMEOUT)
//time out error
else if (error != nil)
//download error
}];
Then use NSCache...
For further explanation: READ HERE
you have to load images asynchronously so tableview can load fast here in your code tableview take so much time because it load image for every cell.
Please check below answer you can find how to load images asynchronously.
https://stackoverflow.com/a/15377082/1713478
Please change url with your url
hope your problem will solved.
Download AFNetworking from this link
https://github.com/AFNetworking/AFNetworking
and then add files to your project and then in .m file
#import "UIImageView+AFNetworking.h"
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
AppDelegate * delegate=(AppDelegate *)[[UIApplication sharedApplication]delegate];
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text=[delegate.firstArray objectAtIndex:indexPath.row];
NSLog(#"%#",delegate.thirdArray);
url = [NSURL URLWithString:[NSString stringWithFormat:#"%#",[delegate.thirdArray objectAtIndex:indexPath.row]]];
[cell.imageView setImageWithURL:url];
return cell;
}
Another answer is to use the amazing SDWebImage framework. It will load your images asynchronously and cache them so if the user has to load the same image again he won't have to download it again.
Here is the link to the framework :
https://github.com/rs/SDWebImage
Here is the code for your cell :
#import <SDWebImage/UIImageView+WebCache.h>
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
AppDelegate * delegate=(AppDelegate *)[[UIApplication sharedApplication]delegate];
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text=[delegate.firstArray objectAtIndex:indexPath.row];
NSLog(#"%#",delegate.thirdArray);
url = [NSURL URLWithString:[NSString stringWithFormat:#"%#",[delegate.thirdArray objectAtIndex:indexPath.row]]];
[cell.imageView setImageWithURL:url];
// [cell.imageView setImageWithURL:url placeholderImage:[UIImage imageNamed:#"placeholder.png"]]; if you want to add a placeholder image
return cell;
}

Fetching and displaying facebook profile picture in a UIImage

I'm trying to make a facebook friend picker displaying the friends who currently have the app installed that are also facebook friends with the current user.
Here I'm fetching the user's facebook profile picture but, I seem to have a warning where the last statement is not used. Thanks for your help.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"friendCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
PFUser *facebookID = [[PFUser alloc] init];
facebookID = [friendUsers objectAtIndex:0];
NSString *fbIdString = [[NSString alloc] init];
fbIdString = [facebookID objectForKey:#"fbId"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
NSURL *profilePictureURL = [NSURL URLWithString:[NSString stringWithFormat:#"https://graph.facebook.com/%#/picture?type=large", fbIdString]];
NSData *picData = [NSData dataWithContentsOfURL:profilePictureURL];
UIImage *fbPic = (UIImage *)[self.view viewWithTag:1001];
[fbPic initWithData:picData];
}
// Configure the cell...
return cell;
}
You need to actually assign the result of the initWithData: call to your fbPic image.
E.g.
fbPic = [fbPic initWithData: picData];
From the apple documentation on UIImage:
- (id)initWithData:(NSData *)data
Parameters
data -
The data object containing the image data.
Return Value
An initialized UIImage object, or nil if the method could not initialize the image from the specified data.
A couple of things:
UIImage *fbPic = (UIImage *)[self.view viewWithTag:1001]; - I think you're trying to get the UIImageView from the cell?
There's no UIImageView where you're actually showing the image.
It should be something like this:
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
NSURL *profilePictureURL = [NSURL URLWithString:[NSString stringWithFormat:#"https://graph.facebook.com/%#/picture?type=large", fbIdString]];
NSData *picData = [NSData dataWithContentsOfURL:profilePictureURL];
UIImageView *fbPicImageView = (UIImageView *)[self.view viewWithTag:1001];
[fbPicImageView setImage:[UIImage imageWithData:picData]];
}

Image lazy loading in table view

I want to use lazy loading of images concept in my table view. My array of image rul string is ( MSMutableArray ) "images". How can I implement this in cellForRowAtIndexPath.
It looks like:
-(UITableViewCell *) tableView:(UITableView *)AtableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell=[searchtable dequeueReusableCellWithIdentifier:#"cell"];
if(!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
cell.textLabel.font=[UIFont systemFontOfSize:12];
cell.imageView.image=[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[appSmallLogos objectAtIndex:indexPath.row]]]];
cell.detailTextLabel.text=[appReleaseDates objectAtIndex:indexPath.row];
}
return cell;
}
Try this code :
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
indicator.frame = CGRectMake(your bounds);
[cell addSubview:indicator];
[indicator bringSubviewToFront:self.view];
[indicator startAnimating];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
//This is what you will load lazily
NSString *u=[NSString stringWithContentsOfFile:r.url encoding:NSUTF8StringEncoding error:nil];
NSURL *imageURL=url;
NSData *image=[NSData dataWithContentsOfURL:imageURL];
dispatch_sync(dispatch_get_main_queue(), ^{
CustomCell *cell = (CustomCell *)[tableView cellForRowAtIndexPath:indexPath];
cell.imageView.image=[UIImage imageWithData:image];
[cell setNeedsLayout];
[indicator stopAnimating];
});
});
cell.cellDescription.text=r.url;// this is which you want to add in first time.
I am not sure but try it.
You can use the SDWebImage library, the library will download and cache the image asynchronously. by passing the url to it as argument
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] autorelease];
}
// Here we use the new provided setImageWithURL: method to load the web image
[cell.imageView setImageWithURL:[NSURL URLWithString:#"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
cell.textLabel.text = #"My Text";
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
TableCellLayout *cell = (TableCellLayout *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[TableCellLayout alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.cellName = [[array valueForKey:#"name"] objectAtIndex:indexPath.row];
cell.cellImage = [UIImage imageNamed:#"placeholder.png"]; // add a placeholder
NSString *imageURL = [[array valueForKey:#"imageLink"] objectAtIndex:indexPath.row];
NSURL *theURL = [NSURL URLWithString:imageURL];
if (asynchronousImageLoader == nil){
asynchronousImageLoader = [[AsynchronousImages alloc] init];
}
[asynchronousImageLoader loadImageFromURL:theURL];
cell.cellImage = asynchronousImageLoader.image;
return cell;
}
I finally managed to do it setting the image with:
– performSelectorOnMainThread:withObject:waitUntilDone:
After the image is downloaded

Cancel Selector in UITableViewCell

I have scenario that in which i am using selector in TableViewCell as bellow and when I click on back button in my view I want to cancel that selector and I am sending dictionary as object in Selector
My code is as bellow
In Header File
NSMutableDictionary* photoDict;
NSMutableDictionary* dictImages;
In .M file
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell==nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
[[NSBundle mainBundle]loadNibNamed:#"MyCellNib" owner:self options:Nil];
cell = detailChainObj;
}
NSString* avatarURL =#"image_Url"; //Any url of image for cell.
NSString *key =[[NSString alloc] initWithFormat:#"Key%d%d",indexPath.section,indexPath.row];
dictImages = [NSDictionary dictionaryWithObjectsAndKeys:imageViewCell,#"Img",imgURL,#"imgURL",key,#"key", nil];
[self performSelectorInBackground:#selector(DownloadLinkzImageOfUser:) withObject:dictImages];
if([photoDic valueForKey:keyAvt])
{
NSData* data = (NSData*)[photoDic valueForKey:key];
imageViewCell.image = [UIImage imageWithData:data];
}
else
{
[self performSelectorInBackground:#selector(DownloadImagesForCell:) withObject:dictImages];
}
}
//
-(void)DownloadImagesForCell:(NSDictionary *)result
{
UIImageView* img = (UIImageView*)[result objectForKey:#"Img"];
NSString* urlAvt = [result valueForKey:#"imgURL"];
if([urlAvt isEqualToString:#"No Image"])
{
img.image = [UIImage imageNamed:#"noimg.png"];
}
else
{
NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imgURL]];
img.image = [UIImage imageWithData:data];
[photoDic setValue:data forKey:[NSString stringWithFormat:#"%#",[result valueForKey:#"key"]]];
}
}
Now I want to cancel this selecter when I press back button
and please keep in mind that I have already use
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(DownloadImagesForCell:) object:dictImages];
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nsobject_Class/Reference/Reference.html
I guess this method works for performSelector:withObject:afterDelay: only.

how to set image in uitable view

I download some images using an NSThread. When all the images are downloaded, I have to put them in cell.myimageview. Give me the solution for setting an image in a user-defined method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
TableCell *cell = (TableCell *)[TableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[TableCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
NSString *bedsbaths=[NSString stringWithFormat:#"Beds:%# Baths:%#",[[AppDeleget.statuses valueForKey:#"beds"] objectAtIndex:indexPath.row],[[AppDeleget.statuses valueForKey:#"baths"] objectAtIndex:indexPath.row]];
cell.mlsno.text=[[AppDeleget.statuses valueForKey:#"mlsno"] objectAtIndex:indexPath.row];
cell.price.text=[[AppDeleget.statuses valueForKey:#"price"] objectAtIndex:indexPath.row];
cell.address.text=[[AppDeleget.statuses valueForKey:#"address"] objectAtIndex:indexPath.row];
cell.bedsbaths.text=bedsbaths;
cell.accessoryType=UITableViewCellAccessoryDetailDisclosureButton;
return cell;
}
-(void)LoadImage
{
for(int x=0;x<[ListPhotos count];x++)
{
NSData *imageData =[ListPhotos objectAtIndex:x];
id path = imageData;
NSURL *url = [NSURL URLWithString:path];
NSLog(#"%#",url);
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data];
[self performSelectorOnMainThread:#selector(downloadDone:) withObject:img waitUntilDone:NO];
}
}
-(void)downloadDone:(UIImage*)img {
// I have to set the cell here. How?
cell.myimageView.image=img
}
In -(void)LoadImage
Store the img in a NSArray.
In - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath , code as
cell.myimageView.image=[imgArray objectAtIndex:indexPath.row];
Assign the delegate and datasource of tableview as,
-(void)downloadDone:(UIImage*)img {
self.tableView.delegate=self;
self.tableView.datasource=self;
}