views:

42

answers:

2

Hi,

I'm having troubles releasing objects.. To explain it better I have included my code below.

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];

How would I release the string and are there any other leaks? Also, if I remove everything from the array records with removeAllObjects, is everything released okay then too? The array should never be released and be available at all time, I'm just worrying about its objects.

Edit: The only leak pointed out had to do with the NSPipe and should be fixed in the code.

Thanks for any help!

+1  A: 

substringToIndex: returns an autoreleased string, so there's no need to release it.

The only memory leak I see is where you set up your 'pipe' var a second time (for the task's standard output) without first releasing its current value (the NSPipe instance used for standard error & input).

Mutable collections like NSMutableArray will retain the objects they contain (as do all mutable/nonmutable collections) then release them when they're removed (or when the collection itself is deallocated).

tedge
Thank you. I fixed the above code.
+3  A: 

Memory management in Objective-C has one fundamental rule:

You take ownership of an object if you create it using a method whose name begins with “alloc” or “new” or contains “copy” (for example, alloc, newObject, or mutableCopy), or if you send it a retain message. You are responsible for relinquishing ownership of objects you own using release or autorelease. Any other time you receive an object, you must not release it.

Thus every call to new in your code sample should be balanced with a call to release or autorelease. The NSArray, along with most other objects in the code, isn't created with either, so it doesn't need to be released. The [NSString alloc] is autoreleased, so it's taken care of. Collections manage their own items, retaining and releasing them as necessary: when an item is inserted, it's retained; when it's removed, it's released. Dictionary keys are copied rather than retained.

Where you've got an unbalanced new (and hence leak) is the first NSPipe you created. Release it before creating the pipe for grep's standard output. Perhaps you simply left it out of the sample, but you're also not setting any arguments for the grep task.

outis
+1 for quoting docs. There's no place that states it better than the memory management documentation.
Chuck
Thanks you! I fixed the NSPipe leak. Yes I left the arguments, etc. out on purpose.