CocoaDev

Edit AllPages

I have a method which resizes an image and adds a drop shadow to it. I’ve determined that it is leaking several NSImage instances. I’ve read up on retain counts, and I think that when I retain “resizedImage,” I increase the retain count such that [resizedImage release]; doesn’t completely release it.

– Matt Ball


(1) That which you retain (or copy, or alloc, or obtain with new), you must release. In the above code I see one alloc, one retain and one release. Aloha, imbalance! You must autorelease resizedImage.

(2) These lines

image = [resizedImage retain]; [resizedImage release];

return image;

do not do anything. Just return resizedImage.

To say just a bit more: the variables image and resizedImage are pointers. When you say image = resizedImage, that doesn’t copy the image object or anything like that, it just means that image will point to the same object that resizedImage points at. If you were to modify resizedImage at this point, image would also be modified (they’re the same object).

Actually, you do have to autorelease resizedImage, so you should do something like this: return [resizedImage autorelease]; to solve the leak –JediKnil

Knil, read what I said. Points one and two.


I’m having a problem because I can’t really balance my allocs and releases. If I release every NSImage except the final one and return [shadowCanvas autorelease]; then it won’t work, because the NSImage chain that shadowCanvas points to will have already been released.

– MattBall


This is the purpose of autorelease - it’s a delayed release. I think you’re confused though - shadowCanvas is a single image object, not a chain. If it needed to hold onto the other images (which it does not), it would retain them. You don’t need to.

copy, alloc, retain, and new count: 9 release and autorelease count: 5

In every method you write (unless you’re doing something complicated, which you are not here) those two numbers should be the same.

Erm, except for accessors, init methods and dealloc methods. In the first two you may wish to increase the retain count of an object, and in dealloc you may want to release some stuff.


There is really no reason to keep changing image, just do something like this (below). Notice how every alloc is balanced with a release or autorelease. –JediKnil


I’m still getting massive amounts (~200) of memory leaks from the function. Here’s a more complete representation of the order of events:

First, my tableView gets the image to be displayed:

shadowedImageWithImage: is using the code JediKnil posted. The cell’s code is as follows:

Thanks

– MattBall

You do need to uncomment that line – it’s essential for a proper accessor method. I looked at my method again, and it’s not doing the leaking - not on its own, at least. Make sure you are using setImage: everywhere you want to change the image ivar. And sorry for missing your post, anonymous. I was in a hurry and didn’t take it in. –JediKnil


I’ve uncommented it, and some people on the cocoa-dev mailing list and I are trying to figure out why it’s crashing. You can catch up here: http://www.cocoabuilder.com/archive/message/cocoa/2005/7/11/141442

– MattBall


Ugh. I just read through the first bunch of posts, and the people replying do not know what they’re talking about.

I should be offended, but I completely failed to solve this problem. Sorry, Matt! –JediKnil On the apple list, knil. :-) And just the first few.

Heh, not a problem :) You definitely helped me clean up my shadowedImageWithImage method, and I think I finally understand the deal with retain and copy. Hopefully I’ll get this crash resolved soon. Thanks for your help thus far.