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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With