views:

523

answers:

2

Running instruments on the device, I intermittently incur a memory leak of exactly 3.5 KB in CFNetwork, the responsible frame being "HostLookup_Master::HostLookup...."

I have read a number of questions re this issue and have separately tried the following to fix the leak:

  1. Included the following in applicationDidFinishLaunching:

    NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil]; [NSURLCache setSharedURLCache:sharedCache]; [sharedCache release];

  2. Specified in the urlrequest not to load from the local cache.

None of the above worked. My class that instantiates the connections does not leak as its instances are released when data has been downloaded. I have verified this by confirming the the living objects of the class is 0 using Instruments.

Any advice on addressing this leak would be greatly appreciated.

+1  A: 

That 3.5kb memory leak sounds familiar, had that when dealing with threads:

@implementation MyClass
+ (void)login
{
    //MyClass *this = [[MyClass alloc] init]; // MEMORY LEAK
    MyClass *this = [[[MyClass alloc] init] autorelease];
    [NSThread detachNewThreadSelector:@selector(anotherThread)
                             toTarget:this
                           withObject:nil];
}

- (void)anotherThread {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [self doStuff];
    //[self release]; // MEMORY LEAK
    [pool release];
}
@end

Every login created 3.5kb leak. Using autorelease solved the problem.

JOM
@JOM For me it looks kind of awkward what you are doing, why do you do this assignment:MyClass *this = [[[MyClass alloc] init] autorelease];"this" is not what you typically use in Obj-C. It makes sense that you leak memory if you do not assign that to self, which is normally used in Obj-C. What I also do not get is that you declare "this" as a local variable. If you return from +(void) login, you are out of scope and your pointer is lost. What you then do in [self release] would be messaging nil which works fine. You are then leaking the "this" variable.
GorillaPatch
@GorillaPatch login is a class method, not an instance method, so there's no "self" being leaked there. The object created, which happens to be called "this" (a poor choice of name IMHO), is the target when -(void)anotherThread is invoked, so it ought to be released at that point.
Tony
@Tony well I got confused by the "this". For me it would make sense that the detached thread takes ownership of the this object and then you can release it in the +login method directly after spawning a new thread. What do you think?
GorillaPatch
@GorillaPatch Since the docs for NSThread say that the target is retained during execution of the new thread, then yes, it makes sense to release it in +login after spawning the thread, rather than in the selector.
Tony
Thanx for code review @GorillaPatch and @Tony! Will rename variable to classObject and change autorelease to [release classObject] in +login.
JOM
A: 

It seems that apple might be aware of the 3.5k leak related to CFNetwork usage and may have been reported as a bug already.

roguepixel
Filing a bug at Apple is a bit like sacrificing a chicken. You are not sure if it helps, but it certainly does not do any harm. ;-)
GorillaPatch