#iphone #objective-c #ipad
#iPhone #objective-c #iPad
Вопрос:
Если бы я писал свой собственный пользовательский метод инициализации, что бы я назвал подходящим вызовом super init be? Иногда я вижу, что это не просто какой-то супер-метод инициализации, а что-то еще, каково общее правило для этого?
Ответ №1:
Классы Objective-C могут иметь несколько init
методов. Обычно один из них называется «Назначенный инициализатор», и именно его вызывают все остальные.
Если вы создаете подкласс и init
метод с другой сигнатурой, вам следует вызвать назначенный инициализатор суперкласса (хотя вызов любого инициализатора суперкласса также будет работать). В документации к классам обычно указывается, что такое назначенный инициализатор.
Например, в UITableViewCell
назначенный инициализатор является initWithStyle:reuseIdentifier:
тем, который вы должны вызвать, если вы создаете подкласс init
метода с другой сигнатурой.
Комментарии:
1. Я думаю, что лучше вызывать назначенный инициализатор в self, а не super, если только вы не кодируете простой инициализатор с именем «init». Следовательно, initWithBlah: должен вызывать «self = [self init]», а не «self = [super init]». Таким образом, если вы когда-нибудь решите переопределить назначенный инициализатор, вы будете готовы
Ответ №2:
Это зависит от контекста, попробуйте ввести несколько nslogs и посмотреть, какой init вызывается для вас. Если это [super init]
или что-то вроде initWithNib…
Комментарии:
1. значит, это зависит от того, в каком super init вызывается? что, если у меня есть два инициализации в super.. Я не буду знать, какие из них вызываются?
2. попробуйте добавить оба
(id)init
и(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
в свой класс, если они отсутствуют. Вставьте NSLog в оба метода и посмотрите, какой из них вызывается вашим кодом при его инициализации сейчас.
Ответ №3:
Создавая свой собственный init
метод, вы должны вызвать super init
, или, если ваш объект связан с xib, вы также можете вызвать super initWithNibName:bundle:
в качестве сокращения, чтобы заставить тот, который реализует ваш объект, использовать один и только один xib. В этом последнем случае вам также следует перегрузить initWithNibName:bundle:
, чтобы выполнить тот же принудительный вызов в случае, если вызывающий его использует.
Если ваш объект включен в XIB, также перегрузите initWithCoder
Комментарии:
1. что означает, что объект включен в XIB, вы имеете в виду, если я создаю подкласс UILabel, а UILabel находится на xib?
2. @xonegirlz : Да, именно это я и имею в виду. Любой пользователь также может поместить любой неграфический объект в xib (я говорю не о представлении в xib, а о самом xib), изменив его атрибут class, чтобы ссылаться на NSString или что-либо еще, и связать его с IBOutlet для создания экземпляра объекта при создании экземпляра XIB.
Ответ №4:
Общее правило заключается в том, что вы должны вызывать [super init]
при инициализации своего класса. Таким образом, метод инициализации класса, который вы наследуете (обычно NSObject), также будет вызван и, таким образом, сконструирован. Если все классы будут следовать этому правилу, будет установлена цепочка инициализаций.
То же правило применяется в dealloc, там вы вызываете [super dealloc]
.
Комментарии:
1. это не очень хорошее правило. Общее правило заключается в вызове назначенного инициализатора суперкласса. Например, если ваш класс наследуется от UIView, вам следует вызвать
[super initWithFrame:]
.