fracturizer
fracturizer

Reputation: 11

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]];
        NSKeyedUnarchiver *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?

Upvotes: 1

Views: 205

Answers (4)

dreamlax
dreamlax

Reputation: 95365

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.

Upvotes: 0

bbum
bbum

Reputation: 162722

The "exact same" code contains an extra line:

[data release];

Upvotes: 1

Antwan van Houdt
Antwan van Houdt

Reputation: 6991

You forgot to release NSData *data. Add the following line after [settingsData release];:

[data release];

Upvotes: 1

Philipp
Philipp

Reputation: 1963

In code sample 1) you release settingsData, while in codesample 2) you are releasing data . Changing that line should solve your issue.

Upvotes: 2

Related Questions