Управление памятью Obj-C для переменной экземпляра NSView * - PullRequest
1 голос
/ 09 января 2011

Мой пользовательский вид имеет подпредставление в качестве переменной экземпляра. Вот пример интерфейса:

@interface MyCustomView : NSView {
    NSView *aSubview;
}

@end

Затем в файле .m я инициализирую aSubView и добавляю его в пользовательское представление.

- (id)init
{
    self = [super initWithFrame:CGRectMakeFrame(0.0, 0.0, 320.0, 480.0);
    if (self) {
        aSubview = [[NSView alloc] initWithFrame(0.0, 0.0, 100.0, 100.0);

        [self addSubview:aSubview];
    }
    return self;
}

Где мне выпустить aSubView?

В методе -dealloc?

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

Или непосредственно после добавления его в пользовательское представление в методе -init?

- (id)init
{
    [...]
    [self addSubview:aSubview];
    [aSubview release];
    [...]
}

Какая реализация лучше?

Ответы [ 3 ]

2 голосов
/ 09 января 2011

В вашем коде есть два сохранения, которые служат разным целям. Лучше держать их отдельно.

Сохранить # 1

Первое удержание подразумевается aSubview = [[NSView alloc] initWithFrame(0.0, 0.0, 100.0, 100.0);. Поскольку aSubview является переменной экземпляра, и вы, похоже, хотите сохранить aSubview в качестве действительной ссылки на представление после запуска инициализатора, имеет смысл, что подразумеваемое сохранение будет сбалансировано release в dealloc .

Сохранить # 2

При добавлении в иерархию представлений ваш экземпляр представления будет сохраняться любым представлением, к которому он относится. То, что это self в этом случае, не имеет значения. Пока представление является частью иерархии представления, это сохранение будет в силе. Когда он будет удален, он будет освобожден.

<Ч />

Это ортогональные реализации продолжительности жизни объекта. Хранение их отдельно делает ваш код менее хрупким.

Например, если в какой-то будущей версии вам придется иногда удалять представление из иерархии представлений с желанием добавить его позже - окончательное показ / скрыть, если хотите, - тогда сохранит # 1 выше сохранит это.

Точно так же, если вы когда-нибудь захотите забыть о текущем представлении, но заменить его другим, вы можете просто сделать:

[aSubview release];
aSubview = [[.... alloc] ... init ... ];

И, в этом случае, retain # 2 выше сохранит старый вид в иерархии представлений.

1 голос
/ 09 января 2011

Я бы предпочел в dealloc, потому что Когда ваш объект содержит другие объекты, вы должны освобождать их всякий раз, когда вы делаете это самостоятельно.

1 голос
/ 09 января 2011

Я бы сказал, что вы должны выпустить "aSubview" сразу после добавления его в представление.(т.е.: как только он будет сохранен в другом месте.)

Однако я бы также сказал, что не имеет смысла иметь «aSubview» в качестве переменной экземпляра - это должна быть просто локальная переменная в вашем методе init.

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