Почему этот код протекает на инструментах? - PullRequest
0 голосов
/ 10 апреля 2011

Я выполняю профилирование памяти на инструментах и ​​чувствую, что у меня есть код, который, кажется, выполняет правильное управление памятью. Однако инструменты убеждены, что я протекаю, и я не могу понять, как устранить утечку.

В моем Event.h у меня есть.


@property (nonatomic, copy) NSString *organizer;
@property (nonatomic, copy) NSString *type;
@property (nonatomic, retain) NSDate *startTime;
@property (nonatomic, retain) NSDate *endTime;
@property (nonatomic, copy) NSString *coverCharge;
@property (nonatomic, copy) NSString *ageLimit;
@property (nonatomic, copy) NSString *dressCode;
@property (nonatomic, copy) NSString *venueName;
@property BOOL attendingFlag;

Они все выпущены в dealloc


- (void) dealloc {
    [type release];
    [organizer release];
    [startTime release];
    [endTime release];
    [coverCharge release];
    [ageLimit release];
    [dressCode release];
    [venueName release];
    [super dealloc];
}   

А в моем заводском классе у меня есть


-(Event*) getEvent:rs {
    Event *event = [[Event alloc] init];
    event.objId = [NSNumber numberWithInt:[rs intForColumn:DATABASE_EVENT_ID_FIELD]];
    event.name= [rs stringForColumn:DATABASE_EVENT_NAME_FIELD];
    event.organizer = [rs stringForColumn:DATABASE_EVENT_ORGANIZER_FIELD];
    event.type = [rs stringForColumn:DATABASE_EVENT_TYPE_FIELD];
    event.desc= [rs stringForColumn:DATABASE_EVENT_DESCRIPTION_FIELD];
    event.venueName = [rs stringForColumn:DATABASE_EVENT_VENUE_NAME_FIELD];
    event.coverCharge= [rs stringForColumn:DATABASE_EVENT_COVER_CHARGE_FIELD];
    event.dressCode = [rs stringForColumn:DATABASE_EVENT_DRESS_CODE_FIELD];
    event.ageLimit = [rs stringForColumn:DATABASE_EVENT_AGE_LIMIT_FIELD];
    event.region = [[[Region alloc] initWithIdAndName:[NSNumber numberWithInt:[rs intForColumn:DATABASE_EVENT_REGION_ID_FIELD]] name:[rs stringForColumn:DATABASE_EVENT_REGION_NAME_FIELD]] autorelease];
    event.community = [[[Community alloc] initWithIdAndName:[NSNumber numberWithInt:[rs intForColumn:DATABASE_EVENT_COMMUNITY_ID_FIELD]] name:[rs stringForColumn:DATABASE_EVENT_COMMUNITY_NAME_FIELD]] autorelease];
    event.address = [rs stringForColumn:DATABASE_EVENT_ADDRESS_FIELD];
    event.address2 = [rs stringForColumn:DATABASE_EVENT_ADDRESS2_FIELD];
    event.city = [rs stringForColumn:DATABASE_EVENT_CITY_FIELD];
    event.state = [rs stringForColumn:DATABASE_EVENT_STATE_FIELD];
    event.zip = [rs stringForColumn:DATABASE_EVENT_ZIP_FIELD];
    event.country = [rs stringForColumn:DATABASE_EVENT_COUNTRY_FIELD];
    event.phone = [rs stringForColumn:DATABASE_EVENT_PHONE_FIELD];
    event.webpage = [rs stringForColumn:DATABASE_EVENT_WEBPAGE_FIELD];

    return [event autorelease];
}

Вы можете заметить, что я устанавливаю больше атрибутов для события, чем я упомянул выше, и это потому, что у меня есть Событие, расширяющее другую сущность, которая является более общей. Причина, по которой я даже не опубликовал этот код, заключается в том, что, согласно инструментам, я использую даже сеттеры для самого класса Event.

Инструменты жалуются, что имеется утечка в распределении событий и еще одна в каждой строке в селекторе getEvent. Rs - это объект набора результатов из библиотеки (FMDB), который я использую во всем приложении, и, похоже, это единственная сущность, в которой обнаруживаются эти утечки, поэтому я уверен, что проблема не в этом. Я на самом деле недавно использовал эту же библиотеку для другого проекта, и не было никаких утечек, вызванных ею, поэтому я устранил ее как источник утечки.

(a) Я явно автоматически высвобождаю объект события, когда возвращаю его.

(b) Все мои сеттеры получают объекты с автоматическим освобождением, поэтому я только увеличиваю количество сохраняемых файлов, как рекомендовано документами по управлению памятью для цели c.

Есть идеи, почему строка alloc и почти каждая следующая за ней строка могут просачиваться?

1 Ответ

1 голос
/ 10 апреля 2011

Ответ в том, что код в другом месте сохраняет ваш объект Event.Утечки могут только показать вам, где была создана утечка памяти, Утечки не могут показать вам код, который должен был быть написан для правильного освобождения объекта после создания!

Все остальные строки помечены как утечки, потому что событиеобъект протекает.

В дополнение к инструменту «Утечки» необходимо добавить инструмент «Выделения» и убедиться, что он установлен на «запись количества ссылок» (мало (i) на панели «Выделения» на графике времени),Затем запустите приложение, наблюдайте за утечкой.Затем выберите инструмент «Распределение», выберите «созданные и все еще живые» и посмотрите на все еще находящиеся объекты «Событие».

Затем нажмите на стрелку рядом с адресом, и вы получите список всех сохранений и выпусков для этого объекта.Обычно из этого можно выяснить, что сохранило объект, который должен был также освободить его позже, но не сделал этого.

...