Подтвердить что ты не робот

Objective-c: Вопросы о self = [super init]


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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

[super init]

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

Ответ 2

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

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

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

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

Думаю, теперь это понятно!!!

Ответ 3

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

Вот выдержка из путеводителя Big Nerd Ranch 3-го издания, глава 2 Цель C, которая разъясняет этот момент

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

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

Этот код показывает, как выполняется выполнение Runtime для iOS

objc_msgSendSuper(self, @selector(init));

Ответ 4

Каждый метод, который вы объявляете, имеет два скрытых параметра: 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

Ответ 5

Из Документация для Apple:

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

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

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

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

Ответ 6

Я бы подумал об этом, поскольку, инициализируя все переменные supers и т.д., вы можете инициализировать переменные расширенных классов до того, как они будут возвращены.

Ответ 7

[super init] совпадает с [ self superclass_variant_of_init]

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

[[self superclass] init];

Ответ 8

Self = [super init];

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

То же самое имя Self здесь, в объекте C,

Согласно JAVA, Супер означает, что разрешить доступ к базовому или родительскому классу

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

Теперь завершите процесс init, чтобы завершить процесс инициализации.