Error in Load image in NSThread? - iphone

I have a url which contain image address, i want to load that image via NSThread but i am facing problem. I am doing thing like this.
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 10, 55, 57)];
[NSThread detachNewThreadSelector:#selector(showImage) toTarget:self withObject:nil];
[self.view addSubview:imageView];
- (void) showImage {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSURL *url = [NSURL URLWithString:temp.strUrl];
UIImage *chart = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
[url release];
imageView.image = chart;
[pool release];
}
Please help me on that.

the problem is here.
[url release];
you are not supposed to release the url object . as you haven't alocated it, may be that is what you are facing problem with.

Related

App getting crash in background image loading iphone

I have scroll view with 60 UIImageView's. Images displaying in these imageviews are from url and url's i get from the webservice. When user scrolls to bottom I call the webservice and get new 60 urls. After getting the url i am utilizing same UIImageView's to display images. Following is my code for displaying images.
for (UIView *viewSel in [scrlView subviews]) {
NSString *strImgUrl = [arrImgURL valueForKey:#"url"];
if ([viewSel isKindOfClass:[UIImageView class]]) {
UIImageView *imgView = (UIImageView *)viewSel;
[imgView setImage:[UIImage imageNamed:#"loading432x520.png"]];
NSMutableArray *arr = [[NSMutableArray alloc] init];
[arr addObject:[NSString stringWithFormat:#"%#",strImgUrl]];
[arr addObject:imgView];
[self performSelectorInBackground:#selector(loadImageInBackground:) withObject:arr];
[arr release];
}
}
- (void) loadImageInBackground:(NSMutableArray *)arr {
NSLog(#"loadImage");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[arr objectAtIndex:0]]];
UIImage *img = [[UIImage alloc] initWithData:imgData];
if (img != nil) {
[arr addObject:img];
}
else{
[arr addObject:[UIImage imageNamed:#"no-image432x520.png"]];
}
[img release];
[self performSelectorOnMainThread:#selector(assignImageToImageView:) withObject:arr waitUntilDone:YES];
[pool release];
}
- (void) assignImageToImageView:(NSMutableArray *)arr{
NSLog(#"assignImage");
UIImageView *imgView = [arr objectAtIndex:1];
imgView.image = [arr objectAtIndex:2];
}
The code works perfect for first time. But when i get new urls it is working some time or getting crash. I don't know why it is getting crash. I want to stop that crash. If you are not getting to my question then let me know. Please help me for this. Thanks in advance. Valid answer will be appreciated.
Thank you all to give your help full comments to my question. I got the error. I am adding CALayer to uiimageview when allocating memory to uiimageview. I remove that CALayer code and it work perfectly. Nikita's comment help me to find my error.

Memory leak Using NSData from URL

I receive Image from URL by threading .
but memory leaking in NSData.
Why? How do I fix it?
Leaking in Iphone devie not in simulator. help me!!
//viewcontroller
-(void)viewDidLoad
{
[self performSelectorInBackground:#selector(loadImageScreenshot:) withObject:args];
}
// loding image
-(void) loadImageScreenshot:(NSDictionary *) args
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIImage * screenshotImage=[UIImage imageWithStringURL:url];
NSDictionary *args2=[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:num], #"screenNum",
screenshotImage,#"image",
nil];
[self performSelectorOnMainThread:#selector(assignImageToScreenshotImageView:) withObject:args2 waitUntilDone:YES];
[pool release];
}
//image add
- (void) assignImageToScreenshotImageView:(NSDictionary *)arg
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIImage * image= [arg objectForKey:#"image"];
UIImageView *imageview=[UIImageView alloc]init];
.
.
imageview.image=image;
[self.mScreenshotSpace addSubview:imageview];
[imageview release];
[pool release];
}
//image from url
+(UIImage *)imageWithStringURL:(NSString *)strURL
{
NSURL *url =[NSURL URLWithString:strURL];
NSData * data=[[NSData alloc]initWithContentsOfURL:url options:NSDataReadingUncached error:&error];
UIImage * image=[UIImage imageWithData:data ];
[data release];
return image;
}
How do you know it is leaking? You are creating an autorelease pool in - (void) assignImageToScreenshotImageView:(NSDictionary *)arg that is never drained, that is a leak.
Otherwise the code seems fine.

Parse image issue in Iphone

I have a array which have a one content image URL for key "Image". I want to show that image in my table view.
How to do it .Please give me suggestion.
You can search in google using "lazy loading image for tableview".
It is also available with apple example.
img_view = [[UIImageView alloc]init];
img_view.autoresizingMask = UIViewAutoresizingFlexibleWidth;
img_view.frame = CGRectMake(0,0,130, 75);
activityIndicator = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge] autorelease];
[img_view addSubview: activityIndicator];
activityIndicator.center = CGPointMake(50,30);
NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc]
initWithTarget:self
selector:#selector(loadImage:)
object:[[xmlParser data1] objectAtIndex:indexPath.row]];
[queue addOperation:operation];
[operation release];
[cell.contentView addSubview:img_view];
-(void)loadImage:(Book *)book
{
[activityIndicator startAnimating];
NSString *imgurl=[book image_url];
NSURL *url=[[NSURL alloc]initWithString:imgurl];
NSData *img=[[NSData alloc]initWithContentsOfURL:url];
UIImage *image=[UIImage imageWithData:img];
img_view.image=image;
[activityIndicator stopAnimating];
}

UIButton image asynchronously

I have a bunch of UIButton in a UIScrollView and each UIButton takes an image from a URL. What is the easiest way so that the image will be loaded asynchronously?
For example, the usual way is:
[button setImage:[UIImage imageWithData:data] forState:UIControlStateNormal];
but this blocks the UI, I don't want it to
You can try this
[self performSelectorInBackground:#selector(loadImag) withObject:nil];
In loadImage function load the image from url and then assign it to the button.
I am not sure this will work for you...As I am a beginner in objective C development
Try with an NSInvocationOperation, make an synchronous request for each image button... Pass the button as parameter, something like this i mean...
Init the operation queue (maybe on init):
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
start the operation invocation for each button...
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
selector:#selector(getImageFromURL:)
object:[NSDictionary dictionaryWithObjectsAndKeys:#"http://getMyImage.com/resource.jpg", #"url", button, #"button", nil]];
[queue addOperation:operation];
[operation release];
this can be your getImageFromURL: selector
- (void) getImageFromURL:(NSDictionary*)dict
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSURL *url = [NSURL URLFromString:[dict objectForKey:#"url"]];
UIButton *button = [dict objectForKey:#"button"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
UIImage *image = [[UIImage alloc] initWithData:data];
// Finally set the button image and release image ...
[pool drain];
}
Don't forget release queue on dealloc...
Hope this helps! :)
I guess it is alright, if you block while loading one single image? The problem is that you have many of them? If so, then I would do like this (no threads needed):
#define DELAY 0.1 // you may set it to 0 as well
...
[self performSelector:#selector(setupButton:)
withObject:[NSNumber numberWithInt:0]
afterDelay:DELAY];
...
-(void)setupButton:(NSNumber*)count
{
UIButton *button = [self buttonFromMyScrollViewWithCount:count.intValue];
[button setImage:...];
if (count.intValue < self.numberOfButtonsInMyScrollView)
[self performSelector:#selector(setupButton:)
withObject:[NSNumber numberWithInt:count.intValue + 1]
afterDelay:DELAY];
}

UIImageView setImage Leaks?

Have been searching for a solution to this problem for endless hours now. The problem is really simple. I have a UIImageView in the nib, i'm loading a image from internet and sets the UIIImageView with the image. I'm releasing the viewController. Dealloc is actually getting called(!) and loads the viewController and the image again. This can be done by entering background mode really easy. The Instrument Leaks doesn't report any leaks, BUT it shows in allocation that it keeps the image in the memory and it keeps growing.
Basic example:
-(id)init {
if((self = [super init])) {
id path = [NSString stringWithFormat:#"http://www.aSite.com/largeImage.jpg"];
NSData* urlData = [[NSData alloc] initWithContentsOfURL:url];
UIImage* img = [[UIImage alloc] initWithData:urlData];
[background setImage:img];
[urlData release];
[img release];
}
return self;
}
-(void)dealloc {
[background release];
[super dealloc];
}
Some people say that UIImageView actually leaks, or actually CGImage. Some people say that Instrument aren't showing correctly. I'm getting Memory Warning after 10-15 times of doing this with a 2.5mb large image. Results are from real device and latest iOS (or atleast 4-5 weeks ago). As UIImageView is used by so many people i thought it would be easy to find the problem or get a fix from apple?
Source of CGImage Leak:
(iphone) UIImageView setImage: leaks?
EDIT: I was abit tierd when i wrote the example. Example is correct now. I have also tried with autoreleased object and same "leak" is still there. Please answer the question if you gonna write an answer.
release the url after setting the image
[background setImage:[UIImage imageWithData:urlData]];
[urlData release];
[img release];
In the following code you are making some mistakes.
[urlData release];
[background setImage:[UIImage imageWithData:urlData]];
you should use
if((self = [super init])) {
id path = [NSString stringWithFormat:#"http://www.aSite.com/largeImage.jpg"];
NSData* urlData = [[NSData alloc] initWithContentsOfURL:url];
UIImage* img = [[UIImage alloc] initWithData:urlData];
[background setImage:img];
[urlData release];
[img release];
}
Can't you replace
[background setImage:[UIImage imageWithData:urlData]];
with
[background setImage:img];
UPDATE
I think this should also help
if((self = [super init])) {
id path = [NSString stringWithFormat:#"http://www.aSite.com/largeImage.jpg"];
NSData* urlData = [[NSData alloc] initWithContentsOfURL:url];
[background setImage:[UIImage imageWithData:urlData]];
[urlData release];
}
Have you tried:
-(id)init {
if((self = [super init]))
{
[background setImage:
[UIImage imageWithData:
[NSData dataWithUrl:
[NSUrl urlWithString:
#"http://www.aSite.com/largeImage.jpg" ]]]
];
}
return self;
}
-(void)dealloc {
[super dealloc];
}
clean and with no memory leaks!