开发者

Objective-C Memory Management Alchemistry: Code causes a leak after being put in a class

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜