简体   繁体   中英

iPhone - Objective-C - Memory Leak with initWithArray

I am using the code below to set my two NSArray ivars:

The issue is, I keep getting a memory leak on the following lines:

followingFriendsArray = [[NSArray alloc] initWithArray:friend.Following];
followerFriendsArray = [[NSArray alloc] initWithArray:friend.Followers];

Is this not the correct way to set ivars from an existing NSArray of items? Any help would be appreciated. I've also tried to autorelease the above two lines, but when I actually access them in another method I get an error that they've already been released.

I have included my Interface and Implementation code below:

Interface .h:

NSArray *followingFriendsArray;
NSArray *followerFriendsArray;

@property (nonatomic, retain) NSArray *followingFriendsArray;
@property (nonatomic, retain) NSArray *followerFriendsArray;

Implementation .m:

- (void)handlerGetFollowingInformation:(id)value {
    BOOL success = [Utility checkWebServiceErrors:value controller:self.navigationController];

    if (success) {
        Friend *friend = (Friend *)value;

        followingFriendsArray = [[NSArray alloc] initWithArray:friend.Following];
        followerFriendsArray = [[NSArray alloc] initWithArray:friend.Followers];
    }
}

This is how I need to access the arrays:

- (void)followersButtonTapped:(id)sender {
    FollowingVC *fvc = [[FollowingVC alloc] initWithNibName:@"FollowingViewController" bundle:nil];

    fvc.friends = followerFriendsArray;

    [self.navigationController pushViewController:fvc animated:YES];
    [fvc release];
}

I release my two ivars in the following way as per usual:

- (void)viewDidUnload {
    self.followingFriendsArray = nil;
    self.followerFriendsArray = nil;
    [super viewDidUnload];
}

- (void)dealloc {
    [followingFriendsArray release];
    [followerFriendsArray release];
    [super dealloc];
}

I mean the code works just fine, it's just that I'm concerned about said memory leaks when I run the "Leaks" performance tool.

OK

you should not use autorelease in this case, but you have to release the arrays by calling :

[followingFriendsArray release];
[followerFriendsArray release];

you can do it:

  1. when you don't need to use them any more.
  2. in the dealloc method in your .m file.

option 2looks like that -

- (void)dealloc {
[followingFriendsArray release];
[followerFriendsArray release];
[super dealloc];
}

BTW - if you don't manipulate the arrays after creating them (add / remove objects) you should use an immutable array (NSArray). Good Luck

Your method handlerGetFollowingInformation is assigning new values to followingFriendsArray and followerFriendsArray without releasing the previous contents. If you call this method more than once on the same instance you will leak.

CRD is right that the arrays are not released inside the handlerGeFollowingInformation method but the fix is maybe overkill. What you need to do is to use self. so that the setter method is called which does that automatically. You could should look like this:

- (void)handlerGetFollowingInformation:(id)value {
    BOOL success = [Utility checkWebServiceErrors:value controller:self.navigationController];

    if (success) {
        Friend *friend = (Friend *)value;

        self.followingFriendsArray = [[NSArray alloc] initWithArray:friend.Following];
        self.followerFriendsArray = [[NSArray alloc] initWithArray:friend.Followers];
    }
}

Easy fix but hard to spot and I ran into this issue over and over again especially when I started to dealloc are the properties.

-Andy

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM