Обновление: эта утечка была решена. Если Вы получаете подобные утечки, и Ваше приложение является многопоточностью, Вы, скорее всего, выполняете вызовы UIKit от фонового потока; используйте, например. [NSThread performSelectorOnMainThread:]
направить UIKit обращается к основному потоку, который является единственным местом, где им позволяют.
Я выполнял Утечки на своем текущем проекте найти утечки в последнее время, и я продолжаю сталкиваться с этими "утечками", которые от того, что я могу сказать, не являются действительно утечками. Следующий код, взятый непосредственно из проекта, имеет две утечки, согласно Утечкам:
- (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];
Я думал, что это удалило утечку, но она не сделала в конечном счете. Таким образом, я все еще в недоумении.
arrayWithArray сохраняет объекты, которые вы сохранили в своем изменяемом массиве. http://www.iphonedevsdk.com/forum/iphone-sdk-development/14285-nsmutablearray-arraywitharray-does-add-retain.html
Я бы рекомендовал выпустить его или, что безопаснее, создавать объекты с установлен атрибут autorelease. При вызове извлечения соседей для индекса сделайте эти объекты автоматически освобожденными, и они будут освобождены, когда массив nsmutable будет освобожден
РЕДАКТИРОВАТЬ: Один совет, который я мог бы добавить при отслеживании ошибок памяти, - это включить зомби и проверить счетчик ссылок ваших объектов. Затем вы можете определить, какие из них не выпускаются, и это должно упростить отслеживание. Эта ссылка покажет вам, как настроить ваш проект xcode для включения зомби: cocoadev.com/index.pl?NSZombieEnabled
Что возвращает retrieveNeighborsForIndex
?
Есть ли шанс, что результат этого метода будет сохранен (не выпущен автоматически)?