Утечки (прибор) сообщает об утечках в автоматически выпущенных объектах - PullRequest
6 голосов
/ 28 июня 2010

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

Я думал, что это устранило утечку, но в конечном итоге это не так. Так что я все еще в растерянности.

Ответы [ 3 ]

2 голосов
/ 16 июля 2010

Антиклиматически, этот вопрос решил сам, когда я решил кучу других проблем с моим кодом.

В основном, в коде было несколько мест, где обновления пользовательского интерфейса производились вне основного потока, что является большим нет-нет. Одна из этих других не связанных с этим проблем должна была вызвать утечку памяти в приведенном выше коде, поскольку она больше не сообщает о каких-либо утечках (у меня 0 утечек в том виде, в каком они есть), хотя я не модифицировал этот код.

0 голосов
/ 29 июня 2010

arrayWithArray сохраняет объекты, которые вы сохранили в свой изменяемый массив. http://www.iphonedevsdk.com/forum/iphone-sdk-development/14285-nsmutablearray-arraywitharray-does-add-retain.html

Я бы порекомендовал выпустить его, или еще безопаснее создать объекты с установленным атрибутом autorelease. При вызове Retrive соседей для индекса, сделайте эти объекты автоматически, и они будут освобождены, когда массив nsmutable будет освобожден

EDIT: Один совет, который я мог бы добавить при отслеживании ошибок памяти, - включить зомби и проверить счетчик ссылок ваших объектов. Затем вы можете определить, какие из них не выпущены, и это должно упростить отслеживание. Эта ссылка покажет вам, как настроить ваш проект xcode для включения зомби: cocoadev.com/index.pl?NSZombieEnabled

0 голосов
/ 28 июня 2010

Что retrieveNeighborsForIndex возвращает?

Есть ли вероятность того, что результат этого метода будет сохранен (не выпущен автоматически)?

...