2013-09-09 5 views
23


Я видел self = [super init] в методах init. Я не понимаю, почему. Не будет [super init] вернуть суперкласс? И если мы укажем self = [super init], неужели мы не получаем self = superclass?
Вот фрагмент пример кодаObjective-c: Вопросы о self = [super init]

- (id)init 
{ 
    if (self = [super init]) { 
     creationDate = [[NSDate alloc] init]; 
    } 
    return self; 
} 

Надежда кто-то может прояснить это для меня. Спасибо.

+1

Поиск "isa pointer". –

+7

Это довольно хорошо объяснено здесь: http://www.cocoawithlove.com/2009/04/what-does-it-mean-when-you-assign-super.html. –

ответ

43

Предполагая, что MyClass является подклассом BaseClass, происходит следующее, когда вы звоните

MyClass *mc = [[MyClass alloc] init]; 
  1. [MyClass alloc] выделяет экземпляр MyClass.
  2. Сообщение об ошибке отправляется в этот экземпляр для завершения процесса инициализации init.
    В этом методе self (который является скрытым аргументом для всех методов Objective-C) является выделенным экземпляром с шага 1.
  3. [super init] называет реализацию суперкласса из init с тем же самым (скрытым) self аргументом , (Это может быть точка, что вы поняли неправильно.)
  4. В init методе BaseClass, self все тот же экземпляр из MyClass. Этот метод суперкласса инициализации может теперь или

    • ли базовую инициализацию self и вернуть self или
    • Отклон self и выделить/инициализации и возвращает другой объект.
  5. Назад в init методом MyClass: self = [super init] теперь либо

    • MyClass объект, который был выделен в шаге 1, или
    • что-то другое. (Вот почему нужно проверять и использовать это возвращаемое значение.)
  6. Инициализация завершена (с использованием , возвращаемого суперклассом init).

Итак, если я правильно понял ваш вопрос, главное, что

[super init] 

называет суперкласс реализации init с self аргументом, который является MyClass объекта, а не BaseClass объект.

+0

На шаге 4 будет ли «другой объект» быть чем-то иным, чем «nil»? –

1

От Apple's Documentation:

Поскольку INIT ... метод может возвращать ноль или объект, отличный от явно выделено, это опасно использовать экземпляр, возвращаемый Alloc или allocWithZone: вместо одного возвращенного инициализатор. Рассмотрим следующий код:

id myObject = [MyClass alloc]; 
[myObject init]; 
[myObject doSomething]; 

Способ инициализации в приведенном выше примере может быть возвращен ноль или могли бы замещены другой объект. Поскольку вы можете отправить сообщение в ноль без повышения исключения, в первом случае ничего не произойдет, кроме (возможно) головной боли отладки. Но вы всегда должны полагаться на инициализированный экземпляр вместо «необработанного» только что выделенного. Следовательно, вы должны вложить сообщение выделения в сообщение инициализации и протестировать объект, возвращенный из инициализатора, перед продолжением.

id myObject = [[MyClass alloc] init]; 
if (myObject) { 
    [myObject doSomething]; 
} else { 
    // error recovery... 
} 
1

Я думаю о нем, как, init'ing все SuperS переменные и т.д., то вы получите инициализировать свои расширенные переменные классов, прежде чем он возвращается.

6

Как у вас есть вопрос self = [super init] в случае, если Условие предлагает конкретное значение.

Прежде всего [super init] дает инициализацию суперкласса существующего класса, который используется в настоящее время. Использование [super init] дает инициализацию суперкласса, которая показывает, что объект существует в классе.

Теперь, когда вы используете self = [super init], это означает, что вы назначаете класс самому себе для дальнейшего использования того же класса.

И в конце вы положите его, если условие равно if(self = [super init]), это означает, что вы проверяете, существует ли объект класса, чтобы не повредить поведение приложения.

Я думаю, что это ясно сейчас !!!

1

[super init] такого же, как [самого superclass_variant_of_init]

Если вы хотите отправить сообщение для суперкласса, есть другой подход (без использования библиотеки времени выполнения):

[[self superclass] init]; 
3

@MartinR имеет очень хороший ответ. Но вы когда-нибудь задумывались, почему «[super init] вызывает суперклассическую реализацию init с тем же самым (скрытым) аргументом self. (Это может быть тот факт, что вы неправильно поняли.)« Работает в своем третьем пункте?

Вот отрывок из Большого Nerd Ranch руководства 3-е издание, глава 2 Objective C, разъясняющих эту точку

«Как делает супер работу? Обычно, когда вы отправляете сообщение объекту, поиск метода этого имени начинается в классе объекта. Если нет такого метода, поиск продолжается в суперклассе объекта . Поиск будет продолжаться до иерархии наследования до тех пор, пока не будет найден подходящий метод .(Если он попадает на вершину иерархии и метод не найден, исключение.)»

«Когда вы отправляете сообщение супер, вы отправляете сообщение для себя, но поиск метода скачет класс объекта и начинается в в суперкласса

этот код показывает, как IOS выполнения выполняет эту задачу

objc_msgSendSuper(self, @selector(init)); 
2

Каждый метод, который вы объявляете, имеет два скрытых параметра: self и _cmd.

Следующий метод:

- (id)initWithString:(NSString *)aString; 

преобразуется компилятором к следующему вызову функции:

id initWithString(id self, SEL _cmd, NSString *aString); 

видеть эту ссылку больше:

http://www.cocoawithlove.com/2009/04/what-does-it-mean-when-you-assign-super.html

1

Само = [super init];

В соответствии с JAVA, это означает указатель на экземпляр сам, поэтому объект может сам послать сообщение.

же meainng из Я здесь в объективном C,

По JAVA, Супер означают, что позволяет получить доступ к базе или родительский класс

же meainng из Супер здесь в объективном C,

init экземпляр для завершения процесса инициализации.