iPhone: How to reduce the memory size of the pic
hi i am working with Twitter, i got problem with images, i have tweet view have UITableview, it contains all tweet with user photo, if i load those photos in each cell when i scroll the UITableview, it scrolling very very slowly please suggest me to reduce the memory size of photos and scroll the UITableView fast.
i heard the thumbnail can reduce the memory size, does it.(if not which metho开发者_如何学Pythond i have to choose and what thumbnail method do's) if so how to do that in this code (table view cell code)
//Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if(!cell) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewStyleGrouped reuseIdentifier:nil] autorelease];
UIImageView *myImage = [[UIImageView alloc]initWithFrame:CGRectMake(6,10,58,60)] ;
NSURL *url = [NSURL URLWithString:[(Tweet*)[tweetArray objectAtIndex:indexPath.row] image_url]]; //here Tweet is other class and image_url is method in the Tweet class
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
[myImage setImage: [UIImage imageWithData:data]];
[cell.contentView addSubview:myImage];
[myImage release];
}
return cell;
}
Thank you,
please suggest me
The reason for slow scroll of the table view is that you are trying to get the image data for every cell on the main thread. UI is getting blocked while it is going to fetch the image data from the URL and, According to me its not good to download images on main thread while table view is also loaded.
Instead of using this approach, You should have to use NSOperationQueue, NSOperation and NSThread for async load of images to the appropriate cell.
If you need more help or simple code like 2-3 function to download images async...
Here are the functions....
Where you are parsing/getting the values only call [self startLoading]; It will load images without blocking UI.
- (void) startLoading {
NSOperationQueue *queue = [[[NSOperationQueue alloc]init]autorelease];
NSInvocationOperation *op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(loadImagesInBackground) object:nil];
[queue addOperation:op];
[op release];
}
-(void) loadImagesInBackground {
int index = 0;
for (NSString urlString in [(Tweet*)[tweetArray objectAtIndex:indexPath.row] image_url]) {
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
[myImageArray addObject: [UIImage imageWithData:data]];
index++;
if(index/3==0)
[self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if(!cell) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewStyleGrouped reuseIdentifier:nil] autorelease];
UIImageView *myImage = [[UIImageView alloc]initWithFrame:CGRectMake(6,10,58,60)] ;
[myImage setImage: [myImageArray objectAtIndex:indexpath.row]];
[cell.contentView addSubview:myImage];
[myImage release];
}
return cell;
}
This article (Download images for a table without threads) might have your answer. There's also this sample in the iOS dev library, which shows how to load images assynchronously, as quickly as possible.
For sure you want to download your images lazily and asynchronously as described by other answerers.
You also probably want to resize it to your thumbnail size and store it in memory at the smaller size. See this article for tutorial and actual usable library code to do that (scroll down past the rant about copy-and-paste development).
EDIT: You clearly need more help with the background download part. Here's how I do it.
Install ASIHTTPRequest, which is a third party library that GREATLY simplifies HTTP client work. Follow the instructions to install it in your project, and make sure you put #include "ASIHTTPRequest.h"
at the top of your .m file.
Then in your tableView: cellForRowAtIndexPath:
, go:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if(!cell) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
UIImageView *myImage = [[UIImageView alloc]initWithFrame:CGRectMake(6,10,58,60)] ;
[cell.contentView addSubview:myImage];
[myImage release];
}
// so at this point you've got a configured cell, either created fresh
// or dequeued from the table's cache.
// what you DON'T have is a pointer to the uiimageview object. So we need to
// go get it.
UIImageView *theImageView;
for (UIView *view in cell.contentView.subviews) {
if ([view isKindOfClass:[UIImageView class]) {
theImageView = view;
break;
}
}
NSURL *url = [NSURL URLWithString:[(Tweet*)[tweetArray objectAtIndex:indexPath.row] image_url]]; //here Tweet is other class and image_url is method in the Tweet class
ASIHTTPRequest *req = [ASIHTTPRequest requestWithURL:url];
[req setCompletionBlock:^{
NSData *data = [req responseData];
// This is the UIImageView we extracted above:
[theImageView setImage: [UIImage imageWithData:data]];
}];
// this will start the request in the background, and call the above block when done.
[req startAsynchronous];
}
// Then return the cell right now, for the UITableView to render.
// The image will get filled in later when it returns from the server.
return cell;
}
精彩评论