Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Leaks (instrument) reports leaks in autoreleased objects

Update: this leak has been solved. If you are getting similar leaks and your application is multi-threading, you are most likely making UIKit calls from a background thread; make use of e.g. [NSThread performSelectorOnMainThread:] to route UIKit calls out to the main thread, which is the only place where they are allowed.

I've been running Leaks on my current project to find leaks lately, and I keep running into these "leaks" which from what I can tell aren't really leaks. The following code, taken directly from the project, has two leaks, according to Leaks:

- (NSArray *)areaForIndex:(int)index 
{
    NSMutableArray *a = [NSMutableArray arrayWithArray:
        [world  retrieveNeighborsForIndex:index]]; // leak 1
    [a insertObject:[references objectAtIndex:index] atIndex:0];
    return [NSArray arrayWithArray:a]; // leak 2
}

Leak 1 goes away if I change the first line to: (see Update 2-3)

Leak 2 goes away if I change the last line to:

    return a;

I can't unfortunately do that with leak 1 because I'm casting an immutable array into a mutable one. Still, arrayWithArray is supposed to autorelease, anyway, so from what I can tell, it shouldn't leak anything. Any ideas why this is happening?

Update: I've tested this on both the device and the Simulator. The leak is there on both. However, on the Simulator I get some additional information about this leak:

The history for the leak goes as follows:

# | Category | Event Type  | Timestamp | RefCt |  Address  | Size | Responsible Library | Responsible Caller
--+----------+-------------+
0 | CFArray  | Malloc      | 00:09.598 |     1 | 0x474f6d0 |   48 | asynchro            | -[muddyGrid areaForIndex:]
1 | CFArray  | Autorelease | 00:09.598 |       | 0x474f6d0 |    0 | Foundation          | NSRecordAllocationEvent
2 | CFArray  | CFRetain    | 00:09.598 |     2 | 0x474f7d0 |    0 | Foundation          | -[NSCFArray retain]
3 | CFArray  | CFRelease   | 00:09.611 |     1 | 0x474f7d0 |    0 | Foundation          | NSPopAutoreleasePool

The things I can discern from the above is that the autoreleased array is somehow retained twice and then autoreleased, leaving retain count at 1. No idea where or why though...

Update 2 & 3: I tried changing the line for Leak 1 to:

    NSMutableArray *a = [[[NSMutableArray alloc] initWithArray:
        [world retrieveNeighborsForIndex:index]] autorelease];

I thought this removed the leak, but it didn't, ultimately. So I'm still at a loss.

like image 420
Kalle Avatar asked Jun 28 '10 18:06

Kalle


1 Answers

Anticlimactically, this one solved itself as I solved a bunch of other issues with my code.

Mainly, the code had a number of places where UI updates were made outside of the main thread, which is a big no-no. One of these other unrelated issues must have triggered the memory leak in the above code, since it doesn't report any leaks anymore (I have 0 leaks as it stands), although I haven't modified the code any.

like image 171
Kalle Avatar answered Nov 09 '22 20:11

Kalle