On Mon, Apr 19, 2010 at 3:09 AM, Henk Kampman <henk.kamp...@secondmove.com>wrote:
> > On 19 apr 2010, at 11:41, Jean-Daniel Dupas wrote: > > > > > > > Le 19 avr. 2010 à 11:35, Henk Kampman a écrit : > > > >> Have a look at the following code > >> > >> -(void) test > >> { > >> testString = NULL; > >> > >> dispatch_async(dispatch_get_global_queue(0, 0), ^{ > >> dispatch_async(dispatch_get_main_queue(), ^{ > >> > >> NSString* aString = [[NSMutableString alloc] init]; > >> NSLog(@"retainCount: %d",[aString retainCount]); > >> > >> testString = [aString retain]; > >> > >> [aString release]; > >> > >> dispatch_async(dispatch_get_main_queue(), ^{ > >> NSLog(@"retainCount: %d",[testString > retainCount]); > >> }); > >> }); > >> }); > >> } > >> > >> As expected the output is: > >> > >> retainCount: 1 > >> retainCount: 1 > >> > >> However when I change [aString release] to [aString autorelease] the > output shows: > >> > >> retainCount: 1 > >> retainCount: 2 > >> > >> Why? > >> > >> BTW I first noticed this behavior when my application started leaking > the QTMovie objects I was creating in a block. > >> > >> - > > > > Because you should never expect something from retainCount. > > See archives for details. > > Are you sure? I'm not using GC and everything executes within the main > thread. > > In this case the retainCount clearly reflects what I'm seeing in my code! > > But lets assume you're correct, it still doesn't explain the memory leak > when I use autorelease instead of release. > Yes, you found something real. When you use dispatch_async to the global concurrent queue, you are not executing on the main thread. Normally in such a situation you need to create an autorelease pool if you're going to use Cocoa. It turns out that dispatch creates an autorelease pool of last resort, but it's not cleared very often, and relying on it is not encouraged. Dispatch doesn't want to take the overhead of creating and destroying autorelease pools every time when some low level systems are not using Objective-C. If you work at the NSOperation level, this is handled. You can clean the memory up more quickly by wrapping your code in an autorelease pool. dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // your code [pool drain]; }); -Ken Cocoa Frameworks > > - Henk > > > > > -- Jean-Daniel > > > > > > > > > > _______________________________________________ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > http://lists.apple.com/mailman/options/cocoa-dev/kenferry%40gmail.com > > This email sent to kenfe...@gmail.com > _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com