Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 08-11-2009, 02:04 AM   #1 (permalink)
Registered Member
 
Join Date: Aug 2009
Posts: 10
faacs is on a distinguished road
Exclamation Memory management problem

Hi,

I am newbie in iphone development and I could solve the problem from last couple of days. I would really appreciate if someone can help me solve the issue. Here is the problem

I am trying to pre fetch last and next image from internet and I have a class for asynchronous download. Following are the two properties I use to pass url and get Image.

Code:
@property (nonatomic, retain) NSString* ImageUrl;
@property (nonatomic, retain) UIImage* Image;
Following lines are from its connectionDidFinishLoading method.
Code:
UIImage* downloadedImage = [[UIImage alloc] initWithData:m_ImageRequestData];
	
		self.Image = downloadedImage;
	
		// release the data object
		[downloadedImage release];
FYI, m_ImageRequestData is has the data and it is successfully converted to UIImage.
Then I call delegate method in calling class to set requested images as current , previous or next.
Quote:
[m_Delegate internetImageReady:self];
Here is code from delegate method that is called
Code:
-(void) internetImageReady:(InternetImage*)downloadedImage
{	
	
	if(downloadedImage.Image != nil)
	{
			//[downloadedImage release];
	if(downloadedImage.imgindx==curr_index)	// current image is downloaded
	
	{
		[currentImg release];
		if(currentImg==nil)
			currentImg=[[UIImage alloc] init];
		
		
		currentImg=downloadedImage.Image;
			
		imgView.image=currentImg;
		
		
		
	}
		else // if previous
			if(downloadedImage.imgindx==curr_index-1)
			{ 
				[prevImg release];
				if(prevImg==nil)
					prevImg=[[UIImage alloc] init];
				
				prevImg=downloadedImage.Image;
			}
			else //if next
				if(downloadedImage.imgindx==curr_index+1)
				{
				
					[nextImg release];
					if(nextImg==nil)
						nextImg=[[UIImage alloc] init];
					nextImg=downloadedImage.Image;
					
				}
				
			
			
	}
}
There is a lot of UIImage allocation going on and actually these are memory leaks of UIImage I want to remove. if I remove these release and allocations the next and previous images are not set to imageview instead they raise exception. In debugger I have checked their values are not nil but still they raise error when assigning them to imageview. So I am releasing and re allocating these variables and now I m getting memory leaks. Any idea where I m missing things?

Its urgent and I m stuck here.
faacs is offline   Reply With Quote
Old 08-11-2009, 05:50 AM   #2 (permalink)
Registered Member
 
Join Date: Aug 2009
Posts: 10
faacs is on a distinguished road
Default

Anyone there?
faacs is offline   Reply With Quote
Old 08-11-2009, 09:49 AM   #3 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

Code:
if(downloadedImage.Image != nil)
{
   //[downloadedImage release];
   if(downloadedImage.imgindx==curr_index)	// current image is downloaded
   {
      [currentImg release];  // Generally speaking, there shouldn't be a reason to release a property like this.  The old value will be released when a new value is passed in.
      if(currentImg==nil)  
         currentImg=[[UIImage alloc] init];  // Never do alloc/init in the same line as assigning to a property.  It's a leak.  You don't need to create an object anyway, since you assign a new value in the next line.
      
      currentImg=downloadedImage.Image;
      imgView.image=currentImg;
   }
You could probably make a small change to this and avoid that leak. I can't tell if 'currentImg' is a local or instance variable, so this assumes it is a property:

Code:
if(downloadedImage.Image != nil)
{
   if(downloadedImage.imgindx==curr_index)	// current image is downloaded
   {
      if([self currentImg]==nil)  
         [self setCurrentImg: [downloadedImage Image]];
      
      imgView.image=currentImg;
   }

Code:
else // if previous
if(downloadedImage.imgindx==curr_index-1)
{ 
   // Same idea here...
   [prevImg release];
   if(prevImg==nil)
      prevImg=[[UIImage alloc] init];
				
   prevImg=downloadedImage.Image;
}
else //if next
if(downloadedImage.imgindx==curr_index+1)
{
   // And here...
   [nextImg release];
   if(nextImg==nil)
      nextImg=[[UIImage alloc] init];
   nextImg=downloadedImage.Image;
}
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick is offline   Reply With Quote
Old 08-11-2009, 10:12 AM   #4 (permalink)
Digital Assertion
 
drewag's Avatar
 
Join Date: Aug 2009
Posts: 268
drewag is on a distinguished road
Default

Just a note. With code like this where you release and test if the variable is nil:
Code:
[prevImg release];
if(prevImg==nil)
   prevImg=[[UIImage alloc] init];
The variable will only be nil before ever being assigned or if you manually set it to nil. Simply releasing the variable, even if it is deallocated, will not set the pointer back to nil. If you really want to do something only if the variable is deallocated you can check the retain count before releasing it (if you do it after you may get a message send error). But normally you should just release it and then reassign it because it not being deallocated assumes that some other piece of code is still using it (if you are retaining and releasing correctly).

Last edited by drewag; 08-11-2009 at 10:15 AM. Reason: typos
drewag is offline   Reply With Quote
Old 08-11-2009, 10:20 AM   #5 (permalink)
Registered Member
 
Join Date: Aug 2009
Posts: 10
faacs is on a distinguished road
Default

Thanks for the reply.
That really make sense and I am already done with the code changes you suggest after revisiting some of memory management articles. Unfortunately I m still getting leaks of UIImage and InternetImage(class for asynchro download image). I really dont know where to release this object.
I alloc and init its(InternetImage) object every time user press next or previous, and then pass call its method to download synchronously with parameter self as delegate. Then from internetdownload class I call delegate(internetImageReady) again with self.
I couldn't figure out other model and neither could remove its leaks.
faacs is offline   Reply With Quote
Old 08-11-2009, 10:37 AM   #6 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

Quote:
Originally Posted by drewag View Post
The variable will only be nil before ever being assigned or if you manually set it to nil. Simply releasing the variable, even if it is deallocated, will not set the pointer back to nil. If you really want to do something only if the variable is deallocated you can check the retain count before releasing it (if you do it after you may get a message send error). But normally you should just release it and then reassign it because it not being deallocated assumes that some other piece of code is still using it (if you are retaining and releasing correctly).
That doesn't make any sense. If the retain count is zero, then the object either doesn't exist or won't exist for very much longer, and if the retain count is non-zero (which is about the only useful info you can get from the retain count), then the object does exist. That's not really any different than what he's already doing.

You are correct that releasing it beforehand doesn't mean it is now nil, but that doesn't invalidate the test. He could, and possibly should, assign nil to the property at a later point in the program. And there is virtually nothing that should be coded against a retain count. That's just plain risky.
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick is offline   Reply With Quote
Old 08-11-2009, 10:46 AM   #7 (permalink)
Digital Assertion
 
drewag's Avatar
 
Join Date: Aug 2009
Posts: 268
drewag is on a distinguished road
Default

Quote:
Originally Posted by BrianSlick View Post
That doesn't make any sense. If the retain count is zero, then the object either doesn't exist or won't exist for very much longer, and if the retain count is non-zero (which is about the only useful info you can get from the retain count), then the object does exist. That's not really any different than what he's already doing.

You are correct that releasing it beforehand doesn't mean it is now nil, but that doesn't invalidate the test. He could, and possibly should, assign nil to the property at a later point in the program. And there is virtually nothing that should be coded against a retain count. That's just plain risky.
Yes you are right. I do not suggest using the retain count as a test, it is the only thing I could think of if he really wanted to do something only when deallocating it. The test is definitely not invalid it will still run for sure. I just know that it took me a little while to realize that it wasn't doing what I wanted it to do (i have done similar things in my code). I tried to write that code when I was releasing something and then only wanted to reassign it if the object was no longer assigned. I just wanted to make sure that he realized what it was doing. With that code he is only going to alloc the variable once, not every time the code is run (unless he resets the variable to nil somewhere else and then the release is worthless.
drewag is offline   Reply With Quote
Old 08-11-2009, 10:48 AM   #8 (permalink)
Digital Assertion
 
drewag's Avatar
 
Join Date: Aug 2009
Posts: 268
drewag is on a distinguished road
Default

Quote:
Originally Posted by faacs View Post
Thanks for the reply.
That really make sense and I am already done with the code changes you suggest after revisiting some of memory management articles. Unfortunately I m still getting leaks of UIImage and InternetImage(class for asynchro download image). I really dont know where to release this object.
I alloc and init its(InternetImage) object every time user press next or previous, and then pass call its method to download synchronously with parameter self as delegate. Then from internetdownload class I call delegate(internetImageReady) again with self.
I couldn't figure out other model and neither could remove its leaks.
Do you think that you could post up your revised code so that it is a little easier for me to look at?
drewag is offline   Reply With Quote
Old 08-12-2009, 03:22 AM   #9 (permalink)
Registered Member
 
Join Date: Aug 2009
Posts: 10
faacs is on a distinguished road
Default

Quote:
Originally Posted by drewag View Post
Do you think that you could post up your revised code so that it is a little easier for me to look at?
I solved rest of the glitches myself. I have been assigning properties with equal(=) operator. Changing it with call to its setter method like [self setNextimg:tempnextimg] solved most of the my problems. On most of the places I was releasing assigned variables after assigning to the properties. So properties were also releasing from memory. I thought both have the same meanings but I guess assigning variable to properties with equal operator means copying pointer and memory allocation remains the same whereas assigning it with its setter method would allocate another memory location and assign.

Please correct me if I m still mistaken. Second thing I m confused, whether assigning nil to property is equal to releasing it or not.

Thanks to everyone for their response.

Regards,
faacs is offline   Reply With Quote
Old 08-12-2009, 08:05 AM   #10 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

Quote:
Originally Posted by faacs View Post
I solved rest of the glitches myself. I have been assigning properties with equal(=) operator. Changing it with call to its setter method like [self setNextimg:tempnextimg] solved most of the my problems. On most of the places I was releasing assigned variables after assigning to the properties. So properties were also releasing from memory. I thought both have the same meanings but I guess assigning variable to properties with equal operator means copying pointer and memory allocation remains the same whereas assigning it with its setter method would allocate another memory location and assign.

Please correct me if I m still mistaken. Second thing I m confused, whether assigning nil to property is equal to releasing it or not.

Thanks to everyone for their response.

Regards,
I'd say you got it.

Assigning any new value to a property, whether nil or otherwise, releases the old value. You only want to release properties in dealloc.
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick is offline   Reply With Quote
Old 08-12-2009, 09:21 AM   #11 (permalink)
Registered Member
 
Join Date: Apr 2009
Posts: 536
eddietr is on a distinguished road
Default

Quote:
Originally Posted by faacs View Post
I solved rest of the glitches myself. I have been assigning properties with equal(=) operator. Changing it with call to its setter method like [self setNextimg:tempnextimg] solved most of the my problems. On most of the places I was releasing assigned variables after assigning to the properties. So properties were also releasing from memory. I thought both have the same meanings but I guess assigning variable to properties with equal operator means copying pointer and memory allocation remains the same whereas assigning it with its setter method would allocate another memory location and assign.
Just to clarify one thing here, the following two statements are identical and do the same thing memory management-wise:

Code:
someObject.someProperty = someValue;

// is exactly the same as:

[someObject setSomeProperty: someValue];
Some people prefer the latter syntax. I prefer the former. But either way, they are the same thing.

One little thing I do to avoid accidentally making direct assignment to an ivar without using the setter, is that I don't name the ivar exactly the same as the property. I usually just put an underscore before it. So like this for example:

Code:
// in the interface:

NSString* _name;

@property (nonatomic, copy) NSString* name;

// then in the implementation:

@synthesize name = _name;

// then the compiler will catch if I accidentally try to do this:

name = someString;

// when I really meant to do this:

self.name  = someString;
eddietr is offline   Reply With Quote
Reply

Bookmarks

Tags
memory management, uiimage

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 314
12 members and 302 guests
chiataytuday, coolman, givensur, glenn_sayers, guusleijsten, jbro, mediaspree, mottdog, mtl_tech_guy, Punkjumper, vilisei, whitey99
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,649
Threads: 94,114
Posts: 402,883
Top Poster: BrianSlick (7,990)
Welcome to our newest member, Anwerbl
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 09:24 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0