简体   繁体   中英

Obj-C, Memory leak confusion

I'm using a NSMutable String to gain a string back from a database query. I've assigned the variable with @"" and then populate if found from the database. I've tried adding autorelease / release but this causes problems with references to the database call.

Can someone point out my error?

I would have typed this code but I felt the analyzer arrows were useful.

在此处输入图像描述

You're creating an autoreleased NSMutableString and assigning the pointer strDBAAppVer to point to it. But then you throw away the reference to that object, and get the pointer strDBAppVer to point to a new object, an NSString with a retain count of 1.

What I think you want is inside your if statement is something like this:

NSString* databaseField = [[NSString alloc] initWithUTF ...etc.]
[strDBAppVer setString: databaseField];
[databaseField release];

strDBAppVer is first set to [NSMutableString stringWithString:@""] , which is reasonable, memory-wise. However, later, you completely re-set the variable to a whole different object , created by alloc / initWithUTF8String: , making strDBAppVer sometimes point to an already-autoreleased object, and sometimes (when the if statement is true) point to an object with retain count +1.

That's why there's a leak but releasing causes issues. If the if statement is true, you've set your variable to point to an object with +1 count, and if it's false, you've set your variable to point to an entirely different object with 0 count.

This looks to me like confusion about mutable strings. Are you aware that, at least in the code posted, you don't actually mutate strDBAppVer ? Try this instead:

NSString* strDBAppVer = @"";

Then, inside your if statement,

strDBAppVer = [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statementAppVer,0)];
//Now, realizing that strDBAppVer has just been reassigned to point
//to an entirely new object, one created with alloc/init, and therefore one that
//needs to be released,
[strDBAppVer autorelease];

Note the autorelease is only inside the if statement, so it doesn't accidentally overrelease your original value of @"" . (Since constant strings shouldn't be released.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM