iPhone NSMutableArray и NSKeyedUnarchiver unarchiveObjectWithFile освобождают странность - PullRequest
0 голосов
/ 07 октября 2010

Я архивирую массив (NSMutableArray) пользовательских объектов, которые реализуют. Как только я загружаю его из файла сохранения в свойство сохранения @property (nonatomic, retain) NSMutableArray * buddies; количество выпусков объекта равно 2 (правильно, это 1 из автоматического выпуска + 1 сохранения свойства), но затем никто не освобождает его, и число сохранения становится равным 1, поэтому, когда я освобождаю его, я получаю - [__ NSArrayM retainCount]: сообщение отправлено на освобожденный экземпляр (я думаю, потому что счет 1 - это авто-релиз)

Вот полный код:

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];
}

Кто-нибудь знает, почему это происходит?

Ответы [ 3 ]

2 голосов
/ 08 октября 2010

Я не могу сказать это лучше, чем это:

Число, возвращаемое retainCount, бесполезно.

Не полагайтесь наэто ни для чего.Используйте инструмент «Утечки» в «Инструментах», чтобы определить, нет ли у вас объектов.


Если вы разбиваетесь, скорее всего, у вас есть зомби.См. это видео , чтобы узнать, как использовать инструменты для поиска зомби.

1 голос
/ 08 октября 2010

Если вам нужно обнулить массив, используйте средство доступа к свойству, чтобы установить для него значение nil:

self.buddies = nil;

Синтезированная реализация решает проблемы управления памятью.Старайтесь по возможности избегать отправки -retain/-release сообщений непосредственно в переменные экземпляра и вместо этого позволяйте методам доступа позаботиться о вас.Это избавит вас от многих хлопот.

0 голосов
/ 08 октября 2010

Вместо того, чтобы выпускать друзей, почему бы просто не сделать [self.buddies removeAllObjects] в начале loadFromDisk.

...