views:

36

answers:

3

I archive an array (NSMutableArray) of custom objects that implement the . Once i load it froma file to a retaining property @property (nonatomic, retain) NSMutableArray *buddies; the release count of the object is 2 (correct, it's 1of autorelease + 1 of retain of the property) but then noone releases it and the retain count becames 1, so when i release it i get -[__NSArrayM retainCount]: message sent to deallocated instance (i think because the 1 retain count is the autorelease)

Here's the full code:

BuddieListViewController.h

#import <UIKit/UIKit.h>
#import "Buddie.h"

@interface BuddieListViewController : UITableViewController {
    IBOutlet NSMutableArray *buddies;
    [...]
}
[...]
@property (nonatomic, retain) NSMutableArray *buddies;
[...]
@end

BuddieListViewController.m

#import "BuddieListViewController.h"
#import "Buddie.h"
#import "PreviewViewController.h"

@implementation BuddieListViewController

@synthesize buddies;
[...]
- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        [self loadFromDisk];
    }
    return self;
}

- (void)loadFromDisk {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsPath = [paths objectAtIndex:0];
    NSString *appFile = [documentsPath stringByAppendingPathComponent:@"BuddieArchive.ark"];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:appFile]) {
        self.buddies = [NSKeyedUnarchiver unarchiveObjectWithFile:appFile];
        NSLog(@"1- buddies retain count %d (should be 2, 1 + 1autorelease)", [buddies retainCount]);
    } else {
        self.buddies = [NSMutableArray arrayWithCapacity:1];
    }
}
[...]
- (IBAction)cancelledBuddie:(NSNotification *)notification
{
    [editingBuddie release];
    NSLog(@"2- buddies retain count %d (should be 2, 1 + 1autorelease)", [buddies retainCount]);
    [buddies release]; 
    [self loadFromDisk];
    [self.tableView reloadData];
}

Has anyone some idea of why this happens?

+2  A: 

I can't say it better than this:

The number returned by retainCount is useless.

Don't rely on it for anything. Use the Leaks tool in Instruments to determine if you're leaking objects.


If you're crashing, it's most likely that you have a zombie. See this video to find out how to use Instruments to find zombies.

Robot K
A: 

Rather than releasing buddies why not just do a [self.buddies removeAllObjects] at the beginning of loadFromDisk.

Ben
+1  A: 

If you need to nullify the array, use the property accessor to set it to nil:

self.buddies = nil;

The synthesized implementation takes care of the memory management issues. Try to avoid sending -retain/-release messages directly to instance variables wherever possible and instead allow the property accessors to take care of things for you. It'll save you a lot of trouble.

jlehr
So you're saying that setting it to nil will release it automatically because of synthesized accessor/setter, right?
w4nderlust
Yep, the synthesized setter method sends a `-release` message to the object currently referenced by the instance variable prior to assigning the new value, which it retains.
jlehr