Reputation: 11597
Sometimes I wonder where I would be able to get great information other than from the stack overflow community. I suppose the Objective-C memory management handbook wouldn't be bad, but I feel like you guys can tell me why as opposed to just what to do.
I have the following code:
NSString* rawTickerData = [[NSString alloc] initWithData: op.requestData encoding:NSUTF8StringEncoding];
NSArray* lines = [rawTickerData componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
for(NSString* line in lines)
{
NSArray* fields = [line componentsSeparatedByString:@","];
if([fields count] > 1)
{
[self.tickerData addObject:fields];
}
}
[rawTickerData release]
Instruments tells me that fields
is leaking, but trying to release it after the if statement or doing an autorelease gives an EXC_BAD_ACCESS.
The same thing happens for lines
. Releasing it anywhere or trying to do autorelease gives EXC_BAD_ACCESS or "trying to double free" (for autorelease).
Yet, instruments is still saying that these are leaking. Am I missing something?
Upvotes: 0
Views: 260
Reputation: 7899
In these cases the best practice is to release your object's at the end of each loop, if you retained them. In this case your fields
variable gets an autorelease
object, the best option is to use an NSAutoReleasePool
to release your objects at the end of the loop.
NSAutoreleasePool *pool;
pool = [[NSAutoreleasePool alloc] init];
NSString* rawTickerData = [[NSString alloc] initWithData: op.requestData encoding:NSUTF8StringEncoding];
NSArray* lines = [rawTickerData componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
for(NSString* line in lines)
{
NSArray* fields = [line componentsSeparatedByString:@","];
if([fields count] > 1)
{
[self.tickerData addObject:fields];
}
[pool drain];
}
[rawTickerData release];
This will flushes all the autoreleased objects if they are don't needed. If you dont use autorelease pool, your objects are living until your method terminates. If this doesn't resolve your leak problem i suggest to initialize your array like this:
NSArray *lines = [[NSArray alloc]initWithArray:[line componentsSeparatedByString:@","]];
//and release at the end of the loop
[lines release];
Upvotes: 0
Reputation: 12112
Unless I'm missing something, the code you've posted is correct. fields
is an autoreleased object that gets retained when added to self.tickerData
. lines
is also autoreleased, so it isn't leaking (at least not in the code shown).
If you're leaking anywhere, it's because you're not properly cleaning up self.tickerData. If you comment out the [self.tickerData addObject:fields];
line, are you still getting leaks reported? If not, make sure you're calling [tickerData release]
(or something similar, like self.tickerData = nil
) somewhere, probably in your dealloc
implementation.
Upvotes: 1