InitWithFrame не вызывается, но awakeFromNib

Я пытаюсь подклассифицировать NSOutlineView. Вот мой код:

OutlineViewSublcass.h:

#import <Cocoa/Cocoa.h>

@interface OutlineViewSubclass : NSOutlineView {

}

@end

OutlineViewSubclass.m:

#import "OutlineViewSubclass.h"

@implementation OutlineViewSubclass

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    printf("debug A\n");
    return self;
}

- (void)awakeFromNib
{
    printf("debug B\n");
}

@end

Отладочный вывод:

debug B

Почему не вызывается (id)initWithFrame:(NSRect)frame?

Ответ 1

Элементы управления

Cocoa реализуют протокол NSCoding для unarchiving из наконечника. Вместо инициализации объекта с использованием initWithFrame: а затем установки атрибутов, метод initWithCoder: берет на себя ответственность за настройку элемента управления при его загрузке с использованием сериализованных атрибутов, настроенных Interface Builder. Это работает почти так же, как любой объект сериализуется с использованием NSCoding.

Это немного отличается, если вы вставляете пользовательский подкласс NSView в нип, который не реализует NSCoding, в этом случае будет вызываться initWithFrame:. В обоих случаях awakeFromNib вызывается после загрузки объекта и обычно является довольно хорошим местом для выполнения дополнительной инициализации в ваших подклассах.

Ответ 2

Официальный ответ Apple для этого Создание пользовательского вида.

Просмотр экземпляров, созданных в Interface Builder , не вызывает initWithFrame: при загрузке файлов nib, что часто вызывает путаницу. Помните, что Interface Builder архивирует объект, когда он сохраняет файл nib, поэтому экземпляр представления уже создан и initWithFrame: уже был вызван.

Метод awakeFromNib обеспечивает возможность инициализации представления, когда он создается в результате загрузки загружаемого файла. Когда загружается файл nib, содержащий объект вида, каждый экземпляр представления получает сообщение awakeFromNib, когда все объекты были удалены. Это дает объекту возможность инициализировать любые атрибуты, которые не архивируются с объектом в Interface Builder.