Objective-C: Трябва ли init методите да се декларират в .h?

Първо, както разбирам, init в Objective-C, функционално е подобен на конструктор в Java, тъй като се използва за инициализиране на променливи на екземпляр и подготовка на клас да свърши някаква работа. Дали това е правилно?

Разбирам, че NSObject имплементира init и като такъв не е необходимо да се декларира в никакви .h файлове.

Но какво ще кажете за персонализирана реализация на init за даден клас, например:

(id) initWithName:(NSString *) name

Трябва ли декларация като тази да бъде посочена като част от .h или не е необходима? Прави ли се по конвенция или има някаква друга аргументация?


person James Raitsev    schedule 19.07.2011    source източник


Отговори (2)


init по никакъв начин не е подобен на конструктора в Java/C++. Конструкторът винаги се изпълнява, когато обектът е създаден. Но изпълнението на init зависи от вас. Ако не изпратите init съобщение след alloc, то няма да се изпълни.

// init does not execute here
MyObject *obj = [MyObject alloc];

И това ще работи без никакви проблеми, ако извлечете от NSObject, тъй като init от NSObject не прави нищо.

Не е необходимо да добавяте init в заглавния файл, защото е наследен от NSObject, но трябва да добавите потребителски методи за инициализация (които не са наследени) към заглавния файл. Обърнете внимание, че методите init са просто нормални методи с конвенция за именуване, но технически няма разлика от другите методи.

Ако не посочите вашите персонализирани методи за инициализация в заглавния файл, но изпратите това съобщение до обект, компилаторът ще генерира предупреждение. Няма да има грешка при компилиране. Така че, ако решите да игнорирате предупреждението, тогава можете да пропуснете и това от заглавката. Но ще получите срив по време на изпълнение, ако методът не е реално приложен. Така че е по-добре да добавите всички методи, които не са наследени в заглавния файл.

person taskinoor    schedule 19.07.2011
comment
Благодаря ти. Ако инициализирам моя клас с персонализиран init метод, това означава ли, че винаги трябва да [super init], за да съм сигурен, че init на NSObjet се извиква поне веднъж? - person James Raitsev; 19.07.2011
comment
Да, трябва да правите това винаги, дори ако init на NSObject не прави инициализация. Това е добра практика и няма проблем, когато се обадите на това. И за повечето от другите класове се изисква инициализация на супер клас. Така че обобщението е: винаги извиквайте метода за инициализация на базовия клас. - person taskinoor; 19.07.2011
comment
Не съм сигурен защо получих отрицателен вот тук. Коментар, обясняващ грешката ми, щеше да ми помогне. - person taskinoor; 27.02.2013

Да, трябва да го декларирате, ако искате да можете да извиквате този персонализиран метод за инициализация (initWithName). И първата мисъл, която трябва да направите в този метод, е да извикате [super init];.

person Pierre Watelet    schedule 19.07.2011
comment
Би било по-добре да се каже, че инициализаторът трябва да извика определения инициализатор на неговия суперклас. Определеният инициализатор не е непременно -init и вие сте свободни да вършите друга работа, преди да извикате определения инициализатор. - person Caleb; 19.07.2011
comment
Не трябва да го декларирате. Той все още ще може да се извиква без декларацията, но ще получавате предупреждения от компилатора, когато се опитвате да го използвате от други класове. - person Richard; 19.07.2011