I came to Objective-C from C++ so I still sometimes has problems understanding memory management of Objective-C. I have a following problem now - XCode Analyzer tells me that object *data causes leaks further in code.
- (void)loadSettings
{
NSString *filePath = [self dataFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
NSData *data = [[NSMutableData alloc]
initWithContentsOfFile:[self dataFilePath]];
NSKeyedUn开发者_JAVA技巧archiver *unarchiver = [[NSKeyedUnarchiver alloc]
initForReadingWithData:data];
// object *data is no longer referenced at this point and has a retain count of +1 (object leaked)
AppData *settingsData = [unarchiver decodeObjectForKey:kDataKey];
if (nil != settingsData)
{
customerVoiceActive = settingsData.customerVoice;
}
[unarchiver finishDecoding];
[unarchiver release];
[settingsData release];
}
}
What drives me crazy is that exactly the same code (except naming) perfectly works and causes no leaks, being placed in applicationDidFinishLaunching:
//load app data
NSString *filePath = [self dataFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
NSData *data = [[NSMutableData alloc]
initWithContentsOfFile:[self dataFilePath]];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]
initForReadingWithData:data];
AppData *appData = [unarchiver decodeObjectForKey:kDataKey];
bCustomerVoice=appData.customerVoice;
[unarchiver finishDecoding];
[unarchiver release];
[data release];
}
What's the difference?
In code sample 1) you release settingsData
, while in codesample 2) you are releasing data
. Changing that line should solve your issue.
You forgot to release NSData *data. Add the following line after [settingsData release];:
[data release];
The "exact same" code contains an extra line:
[data release];
settingsData
should NOT be released, because it was not obtained through a method that implies that you own the returned object. However, you MUST release data
, because you allocated it yourself, and this implies ownership.
精彩评论