Как работает наследование от NSObject? - PullRequest
4 голосов
/ 26 августа 2009

В Objective-C есть пара вещей, которые меня смущают:

Во-первых, в руководстве target-c совершенно ясно, что каждый класс должен вызывать метод init своего подкласса. Немного неясно, должен ли класс, который наследуется непосредственно от NSObject, вызывать свой метод init. Это тот случай? И если так, то почему?

Во-вторых, в разделе о NSObject есть это предупреждение:

Класс, который не должен наследовать какое-либо специальное поведение от другого класса, должен, тем не менее, быть подклассом класса NSObject. Экземпляры класса должны по крайней мере иметь способность вести себя как объекты Objective-C во время выполнения. Наследовать эту способность от класса NSObject намного проще и гораздо надежнее, чем заново изобретать ее в новом определении класса.

Значит ли это, что мне нужно указать, что все объекты явно наследуются от NSObject? Или это как Java / Python / C #, где все классы являются подтипами NSObject? Если нет, есть ли причина создавать корневой класс, отличный от NSObject?

Ответы [ 4 ]

6 голосов
/ 26 августа 2009

1) Каждый раз, когда объект выделяется в Objective-C, его память обнуляется и должна быть инициализирована вызовом init. Подклассы NSObject могут иметь свои собственные специализированные подпрограммы init, и в начале они должны называть свою подпрограмму суперкласса 'init примерно так:

self = [super init];

Идея состоит в том, что все init процедуры в конечном итоге достигают NSObject init.

2) Вы должны четко указать наследование:

@instance myClass : NSObject { /*...*/ } @end

Нет никакой причины иметь корневой класс, кроме NSObject - многие Objective-C в значительной степени полагаются на этот класс, поэтому попытка обойти его приведет к тому, что вы без необходимости будете стрелять себе в ногу.

2 голосов
/ 26 августа 2009

Поскольку возможно наследование от различных корневых базовых классов, да, вы должны явно объявить, что наследуете от NSObject, когда создаете какой-либо новый класс (если, конечно, вы уже не создаете подклассы для чего-то другого, что, в свою очередь, вероятно, подклассы NSObject).

Почти никогда не существует необходимости создавать свой собственный базовый класс, и это не будет легко сделать.

1 голос
/ 26 августа 2009

Objective-C может иметь несколько корневых классов, поэтому вам необходимо четко указать наследование. IIRC NSProxy - еще один корневой класс. Скорее всего, вы никогда не захотите или не захотите создать свой собственный корневой класс, но они существуют.

Что касается вызова init NSObject, то это часть пользовательских и часть безопасности. Init NSObject может ничего не делать сейчас, это не гарантирует, что будущее поведение не изменится. Вызовите init, чтобы быть в безопасности.

0 голосов
/ 26 августа 2009

Вам нужно вызвать [super init], потому что за инициализацией есть код, который вам не нужно писать, потому что он написан для вас в NSObjects init, например, вероятно, фактическое распределение памяти и т. Д.

...