Shizdom
Shizdom

Reputation: 13

NSDictionary leak misunderstanding

Please someone tell me why retaining NSMutabledictionary after some operations is ok, but retain on creation gives a leak.

-(void) Func2
{
    NSString *_errorDesc;
    NSPropertyListFormat format;
    NSString *_plistPath = [[NSBundle mainBundle] pathForResource:@"List" ofType:@"plist"];
    NSData *_plistData = [[NSFileManager defaultManager] contentsAtPath:_plistPath];
    NSDictionary *dataDict = (NSDictionary *) [NSPropertyListSerialization
                                               propertyListFromData:_plistData
                                               mutabilityOption:NSPropertyListMutableContainersAndLeaves
                                               format:&format
                                               errorDescription:&_errorDesc];



    for (int i = 0; i<[dataDict count]; i++)
    {
        [_ups setObject:[NSArray arrayWithObjects:[NSNumber numberWithInt:0],[NSNumber numberWithInt:0], nil]forKey:[NSString stringWithFormat:@"%d",i]];
    }

    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:_ups forKey:@"Ups"];
    [defaults synchronize];

}

-(void) Func1
{
    _ups = [NSMutableDictionary dictionary];
    //_ups = [[NSMutableDictionary dictionary]retain]; = leak
    //_ups = [[NSMutableDictionary alloc]init]; = leak


    if(![[NSUserDefaults standardUserDefaults] objectForKey:@"Ups"])
    {
        [self Func2];
    }else{
        _ups = [[NSUserDefaults standardUserDefaults] objectForKey:@"Ups"];
    }
    [_ups retain]; // - ok
}

Instruments->Leaks shows that leak detected only when I trying to retain on creation, but if I retain after filling a dictionary all fine.

Thanks.

Upvotes: 1

Views: 414

Answers (1)

zaph
zaph

Reputation: 112857

Looking at just one of the if paths (the second) reduces to this:

_ups = [[NSMutableDictionary alloc]init];

// Returns a retained instance assigned to _ups.

_ups = [[NSUserDefaults standardUserDefaults] objectForKey:@"Ups"];

// Now a new instance is assigned to "_ups` without releasing the first instance.

[_ups retain];

//The above retain is incorrect since the method name does not start with "new" or have "copy" in it. This implies that the returned value should be autoreleased. Review Objective-C naming conventions. See Apple's Objective-C Conventions.

All in all, best practice is to use ARC. With ARC the first instance would have been automatically released.

Upvotes: 1

Related Questions