views:

535

answers:

2

I'm writing an iPhone app. I have a header file that looks like this:


@interface EditTagsViewController : UITableViewController {
  NSMutableArray *allTags;
  NSMutableArray *selectedTags;
  NSInteger currentFavorite;
}
@property (nonatomic, retain) NSMutableArray *allTags;
@property (nonatomic, retain) NSMutableArray *selectedTags;
@property (nonatomic) NSInteger currentFavorite;
@end

In the implementation file, my viewDidLoad method looks like this:


- (void)viewDidLoad {
  NSMutableArray *aTags = [[NSMutableArray alloc] initWithArray:[Tag findAllTags]];
  self.allTags = aTags;
  [aTags release];

  NSMutableArray *sTags = [[NSMutableArray alloc] initWithArray:[Tag findByFavoriteId:currentFavorite]];
  self.selectedTags = sTags;
  [sTags release];

  UIBarButtonItem *add = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addNewTag:)];
  self.navigationItem.rightBarButtonItem = add;
  [add release];
  [super viewDidLoad];
}

Here is my dealloc method:


- (void)dealloc {
  [allTags release];
  [selectedTags release];
  [super dealloc];
}

What's confusing to me is that when I run the app both in the simulator and on the device itself, using Instruments (memory leaks), it tells me that this line in my viewDidLoad method is leaking an array:


self.selectedTags = sTags;

It's confusing because I'm using the exact same technique with 2 different variables, and yet no leak is reported with the first one.

I feel like I'm missing something obvious here. Any ideas?

A: 

Have a look at findByFavoriteId is there a retain there? That is the only difference I can see between the aTags and sTags are used in your example

hhafez
+1  A: 

Your code looks correct to me. Is it possible that one of [Tag findAllTags] or [Tag findByFavoriteId:] is leaking? Are you making sure to set self.allTags and self.selectedTags to nil in dealloc?

Be mindful of the difference between saying self.allTags = ... and allTags = .... Because allTags is a property and has the retain attribute, whenever you assign via self.allTags = ..., it implicitly calls the setter method [self setAllTags:...], which invokes retain on the new value and release on the old value (if any). You're doing it correctly in this code sample, but if elsewhere you're assigning straight to allTags (without the self.), you're not releaseing the old value, which may be the source of the leak. Likewise for selectedTags.

Adam Rosenfield