Обновление: эта утечка устранена. Если вы получаете подобные утечки и ваше приложение является многопоточным, вы, скорее всего, делаете вызовы 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];
Я думал, что это устранило утечку, но в конечном итоге это не так. Так что я все еще в растерянности.