головоломка об управлении памятью Objective-C - PullRequest
0 голосов
/ 06 декабря 2011

Это один сегмент кодов, используемый в одном из моих проектов для управления одним экземпляром моего класса:

@interface C: NSObject
{
    NSMutableArray *myArr;
}

@property (nonatomic,retain) NSMutableArray *myArr;

//...

@end

@implementation C

@synthesize myArr;

//...

-(id)init
{
//...
    myArr = [[NSMutableArray alloc] init];
//...
}

//version 1 of dealloc method
-(void)dealloc
{
//...
        self.myArr = nil;
//...
}

//version 2 of dealloc method
-(void)dealloc
{
//...
    [myArr release];
//...
}

здесь метод dealloc версии 1 не работает, а Xcode говорит что-то вроде "EXC_BAD_ACCESS... "и приложение упало.если я изменил метод dealloc как версию 2. он работает.

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

Ответы [ 3 ]

2 голосов
/ 06 декабря 2011

Как сказал Дункан, ошибка EXEC_BAD_ACCESS означает, что объект больше не существует.

Вероятно, это связано с тем, что myArr освобождается до вызова dealloc.

Чтобы упростить управление памятью и отслеживать количество ссылок, я хотел бы сделать это более понятным в методах init, например:

-(id)init
{
//...

    NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:0];
    self.myArr = array;
    [array release];

//...
}

Используя сгенерированный установщик self.myArr = array;, вы гарантируете, что счетчик ссылок корректно сбрасывается, он освободит старое значение и сохранит новое для вас.

@ MadhavanRP: если собственность является оставленной собственностью:

@property(nonatomic, retain) NSMutableArray *myArr;

вызывающий

self.myArr = nil

точно так же, как звонить

[myArr release];
myArr = nil;

Редактировать: @Sylvain избили меня до этого:)

1 голос
/ 06 декабря 2011

Это нормально, даже если это плохая идея / сбивать с толку одинаковое имя для iVar и свойства.Я удалил декларацию iVar.

@interface C: NSObject
{}

@property (nonatomic,retain) NSMutableArray *myArr;

//...

@end

Создайте свой iVar с помощью @ synthetize.

@implementation C

@synthesize myArr = _myArr;

//...

Ваш инициализация неверна.Вы назначаете iVar без использования метода установки.

-(id)init
{
    //...
    // You were doing
    // _myArr = [[NSMutableArray alloc] init];
    // You should do
    NSMutableArray array = [[NSMutableArray alloc] init];
    self.myArr = array;
    [array release];
    // You could avoid the temporary variable but this confuse XCode static analyzer
    //...
}

Это нормально.Я думаю, что @synthetize создал еще один iVar для поддержки вашей собственности.Этот другой iVar не был назначен должным образом.

Вы не заметите этого, если не используете self.myArr (или эквивалент [self myArr]).

Эта путаница является основной причиной, почему хардкорПрограммист ObjC не любит новое свойство вещи.:) Это сбивает с толку новых программистов.

//version 1 of dealloc method
-(void)dealloc
{
    //...
    self.myArr = nil;
    //...
}

Это не хорошо, когда вы обходите установщик, как в методе init.Это работало в любом случае.

//version 2 of dealloc method
-(void)dealloc
{
//...
    [myArr release];
//...
}
0 голосов
/ 06 декабря 2011

Похоже, что ваш объект myArr обменивается сообщениями, когда он не должен быть, в первом случае вы скрываете проблему, устанавливая его равным nil, во втором - нет.Любой метод не должен падать.Когда вы звоните [super dealloc];(вы должны вызвать его в конце реализации dealloc).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...