2010-03-09 3 views
0

У меня возникают проблемы с выпуском объектов. Чтобы объяснить это лучше, я включил свой код ниже.Управление памятью какао NSArray с объектами

NSTask *task = [NSTask new]; 
NSTask *grep = [NSTask new]; 
NSPipe *pipe = [NSPipe new]; 

[task setStandardError: pipe]; 
[grep setStandardInput: pipe]; 
[pipe release]; 
pipe = [NSPipe new]; 
[grep setStandardOutput: pipe]; 

[task launch]; 
[grep launch]; 

NSString *string = [[[[[[NSString alloc] initWithData: [[[grep standardOutput] fileHandleForReading] readDataToEndOfFile] encoding: NSASCIIStringEncoding] autorelease] componentsSeparatedByString: @" "] objectAtIndex: 3] substringToIndex: 8]; 

NSMutableDictionary *dict = [NSMutableDictionary new]; 
[dict setObject: string forKey: @"myKey"]; 
[records addObject: dict]; 
[dict release]; 

[task release]; 
[grep release]; 
[pipe release]; 

Как я могу освободить строку и есть ли какие-либо другие утечки? Кроме того, если я удаляю все из массива records с removeAllObjects, все ли выпущено нормально? Массив никогда не должен выпускаться и быть доступным в любое время, я просто беспокоюсь о его объектах.

Редактировать: Единственная обнаруженная утечка связана с NSPipe и должна быть зафиксирована в коде.

Спасибо за помощь!

+0

ОК, ваш код для назначения строки является просто орехом. Разбить его на более мелкие линии, а утечки и т. Д. Станут намного более очевидными. –

ответ

4

Управление памятью в Objective-C имеет один fundamental rule:

Вы берете право собственности на объект, если вы создаете его, используя метод, имя которого начинается с «Alloc» или «новый» или содержит «копию» (например, alloc, newObject или mutableCopy), или если вы отправите ему сообщение сохранения. Вы несете ответственность за отказ от владения собственными вами объектами с помощью выпуска или авторекламы. В любое другое время, когда вы получаете объект, вы не должны его отпускать.

Таким образом, каждый вызов new в вашем образце кода должны быть сбалансированы с вызовом release или autorelease. NSArray, как и большинство других объектов в коде, не создается ни одним из них, поэтому его не нужно выпускать. [NSString alloc] автореализован, поэтому он позаботился. Коллекции управляют своими собственными предметами, сохраняя и освобождая их по мере необходимости: когда элемент вставлен, он сохраняется; когда он будет удален, он будет выпущен. Словарные ключи копируются, а не сохраняются.

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

+0

+1 для цитирования документов. Там нет места, где это лучше, чем документация по управлению памятью. – Chuck

+0

Спасибо! Я исправил утечку NSPipe. Да, я оставил аргументы и т. Д. Специально. – Jef

1

substringToIndex: возвращает строку с автореализацией, поэтому нет необходимости в release.

Единственная утечка памяти, которую я вижу, - это то, где вы устанавливаете свой «труба» var второй раз (для стандартного вывода задачи), не высвобождая сначала его текущее значение (экземпляр NSPipe, используемый для стандартной ошибки &).

Взаимозаменяемые коллекции, такие как NSMutableArray, сохраняют содержащиеся в них объекты (как и все изменяемые/не подлежащие копированию коллекции), затем освобождают их при их удалении (или когда сама коллекция освобождается).

+0

Спасибо. Я исправил вышеуказанный код. – Jef