开发者

Memory Management in Objective-C when dealing with NSMutableArray

开发者 https://www.devze.com 2022-12-17 20:49 出处:网络
In Instruments the tempPlayer object is showing a leak. In this code, in every for loop I keep on allocating a new tempPlayer instance, set its playerCode variable with a string and add it to an NSMut

In Instruments the tempPlayer object is showing a leak. In this code, in every for loop I keep on allocating a new tempPlayer instance, set its playerCode variable with a string and add it to an NSMutableArray in each iteration. Instruments shows me a leak in the alloc statement. Is there any way to prevent tat leak in the tempPlayer object ?

 for(int i = 0 ; i < [开发者_开发知识库homeLineupArray count] ; i++) {   
    NSArray * tildeSeperator = [[homeLineupArray objectAtIndex:i] componentsSeparatedByString:@"~"];

    [self.tempPlayer release];
    self.tempPlayer = [[LineUpsPlayer alloc] init];
    tempPlayer.playerCode = [tildeSeperator objectAtIndex:0];

    [matchLineUp.homeTeamPlayingEleven addObject:tempPlayer ];
}

Thanks Harikant Jammi


I would simply do this.

for(int i = 0 ; i < [homeLineupArray count] ; i++) {   
    NSArray *tildeSeperator = [[homeLineupArray objectAtIndex:i] componentsSeparatedByString:@"~"];

    LineUpsPLayer *player = [[[LineUpsPlayer alloc] init] autorelease];
    player.playerCode = [tildeSeperator objectAtIndex:0];
    [matchLineUp.homeTeamPlayingEleven addObject:player];
}

You can also replace your loop with this:

for (NSString *lineup in homeLineupArray) {
    NSArray *tildeSeparator = [lineup componentsSeparatedByString:@"~"];
    ...
}

You don't usually want to save each item while iterating through an array to an instance variable since it keeps changing and you only reference it in the method.


Rather than using the property, tempPlayer, use a local variable, and release after adding to the array:

for(int i = 0 ; i < [homeLineupArray count] ; i++) {   
    NSArray * tildeSeperator = [[homeLineupArray objectAtIndex:i] componentsSeparatedByString:@"~"];

    LineUpsPlayer* tempPlayer = [[LineUpsPlayer alloc] init];
    tempPlayer.playerCode = [tildeSeperator objectAtIndex:0];

    [matchLineUp.homeTeamPlayingEleven addObject:tempPlayer ];
    [tempPlayer release];
}

The array retains the objects you add - that's why you need to release the temporary object too.


Things may depend on how do you declare your tempPlayer property in your class (and as it looks that it is temporary object, consider do you need a property accessor for it?)

for(int i = 0 ; i < [homeLineupArray count] ; i++) {   
    NSArray * tildeSeperator = [[homeLineupArray objectAtIndex:i] componentsSeparatedByString:@"~"];

    [self.tempPlayer release]; // Decrease retain count 
    self.tempPlayer = [[LineUpsPlayer alloc] init]; // retain count increase by 1 or 2
    tempPlayer.playerCode = [tildeSeperator objectAtIndex:0];

    [matchLineUp.homeTeamPlayingEleven addObject:tempPlayer]; // retain count increase
}

So as you can see you retain your object more times then you release it so it eventually leaks. Probably your code may be rewritten this way:

for(int i = 0 ; i < [homeLineupArray count] ; i++) {   
        NSArray * tildeSeperator = [[homeLineupArray objectAtIndex:i] componentsSeparatedByString:@"~"];

       LineUpsPlayer* tempPlayer = [[LineUpsPlayer alloc] init]; // object's retain count is 1
        tempPlayer.playerCode = [tildeSeperator objectAtIndex:0];

        [matchLineUp.homeTeamPlayingEleven addObject:tempPlayer]; // container takes ownership of the object
        [tempPlayer release]; // we do not need to own this object as it is in container now
    }


As said above, I normally use a local variable to populate the mutable array. In other cases Instruments didnt show me any leak. So is this the right way to go about ?

for(int i =0 ; i <  ([arrayOfHomePlayers count]); i++ ) //creating home players detials object
{

    localString = [NSMutableString string];
    localString = [arrayOfHomePlayers objectAtIndex:i] ;
    NSArray * localPlayersArray = [localString componentsSeparatedByString:@"~"] ;
    localPlayerPosition = [ [PlayerPosition  alloc] init] ;

    NSArray * playerNameArray = [[localPlayersArray objectAtIndex:0] componentsSeparatedByString:@" "] ;
    localPlayerPosition.globalID   = [localPlayersArray objectAtIndex:1];

    [(teamFormationDetails.homePlayerList) addObject:localPlayerPosition] ;
    [localPlayerPosition release] ;


First, you could change the release to an autorelease and move it to the line after the self is assigned.

Second, the addobject is adding it to a collection which retains it, and I don't see you removing it from that collection, so that's your 'leak'. However, I'm not sure there even is a leak, if you intended to leave it in the collection.

0

精彩评论

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

关注公众号