Обновление: эта утечка устранена. Если вы получаете подобные утечки и ваше приложение является многопоточным, вы, скорее всего, делаете вызовы UIKit из фонового потока; использовать, например, [NSThread performSelectorOnMainThread:]
для маршрутизации вызовов UIKit к основному потоку, который является единственным местом, где они разрешены.
В последнее время я использовал Leaks в моем текущем проекте, чтобы найти утечки, и я продолжаю сталкиваться с этими «утечками», которые, насколько я могу судить, на самом деле не являются утечками. Согласно 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
}
Утечка 1 исчезнет, если я изменю первую строку на: (см. Обновление 2-3)
Утечка 2 исчезнет, если я изменю последнюю строку на:
return a;
К сожалению, я не могу сделать это с утечкой 1, потому что я преобразую неизменяемый массив в изменяемый. Тем не менее, arrayWithArray в любом случае должен автоматически выпускаться, поэтому, насколько я могу судить, он ничего не должен просачиваться. Есть идеи, почему это происходит?
Обновление: я тестировал это как на устройстве, так и на симуляторе. Утечка есть на обоих. Однако на Симуляторе я получаю дополнительную информацию об этой утечке:
История утечки выглядит следующим образом:
# | 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
Из вышесказанного я могу различить то, что автоматически выпущенный массив каким-то образом сохраняется дважды, а затем автоматически освобождается, оставляя счетчик сохранения на 1. Не знаю, где и почему, хотя ...
Обновление 2 и 3: я попытался изменить строку для утечки 1 на:
NSMutableArray *a = [[[NSMutableArray alloc] initWithArray:
[world retrieveNeighborsForIndex:index]] autorelease];
Я думал, что это устранило утечку, но в конечном итоге этого не произошло. Так что я все еще в растерянности.