Что собой представляет собой в ObjC? Когда я должен его использовать?

Что self означает в Objective-C? Когда и где его использовать? Это похоже на Java?

    self относится к экземпляру текущего classа, в котором вы работаете, и да, это аналогично this в Java.

    Вы используете его, если хотите выполнить операцию над текущим экземпляром этого classа. Например, если вы пишете метод экземпляра в classе и хотите вызвать метод на том же экземпляре, чтобы что-то сделать или получить некоторые данные, вы должны использовать self :

     int value = [self returnSomeInteger]; 

    Это также часто используется для методов доступа к экземпляру (например, сеттерам и геттерам), особенно с помощью методов setter, если они реализуют дополнительные функции, а не просто устанавливают значение переменной экземпляра, так что вам не нужно повторять этот код и когда вы хотите установить значение этой переменной, например:

     [self setSomeVariable:newValue]; 

    Одно из самых распространенных применений self – во время инициализации classа. Пример кода может выглядеть так:

     - (id)init { self = [super init]; if(self!=nil) { //Do stuff, such as initializing instance variables } return self; } 

    Это вызывает инициализатор суперclassа (через super ), в результате которого цепочка инициализации происходит по иерархии classов. Возвращенное значение затем устанавливается в self , однако, поскольку инициализатор суперclassа может возвращать другой объект, кроме суперclassа.

    self является подразумеваемым аргументом для всех методов Obj-C, которые содержат указатель на текущий объект в методах экземпляра и указатель на текущий class в методах classа.

    Другим подразумеваемым аргументом является _cmd , который является селектором, который был отправлен методу.

    Имейте в _cmd что вы получаете только self и _cmd в _cmd Obj-C. Если вы объявите метод C (++), например, как обратный вызов из некоторой библиотеки C, вы не получите self или cmd.

    Для получения дополнительной информации см. Раздел « Использование скрытых аргументов » в Руководстве по программированию времени Objective-C.

    Да, это точно так же, как «это» в Java – он указывает на «текущий» объект.

    Две важные заметки:

    1. Сам class, например UIView (я не говорю о объекте UIView ), сам по себе является объектом, и с ним связан сам. Так, например, вы можете ссылаться на self в методе classа следующим образом:

       // This works +(void) showYourself { [self performSelector: @selector(makeTheMostOfYourself)]; } // Class method! +(void) makeTheMostOfYourself { } 
    2. Обратите внимание, что компилятор НЕ подготавливает никаких предупреждений или ошибок, даже если self вы хотите ссылаться, является объектом, а не classом. ОЧЕНЬ легко вызвать аварии таким образом, например:

       // This will crash! +(void) showYourself { [self performSelector: @selector(makeTheMostOfYourself)]; } // Object method! -(void) makeTheMostOfYourself { } // This will crash too! -(void) showYourself2 { [self performSelector: @selector(makeTheMostOfYourself2)]; } // Class method! +(void) makeTheMostOfYourself2 { } 

      К сожалению, это делает методы classа более сложными в использовании, что является неудачным, потому что они являются ценным инструментом для инкапсуляции посредством скрытия информации. Просто будь осторожен.

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

    Прежде всего: очень сложно сравнить концепцию обмена сообщениями / вызова в контексте раннего связывания, статического языка ввода в виде Java с поздним связыванием, динамически типизирующих языков как Objective-C. В какой-то момент это сломается. Я бы сказал: Нет, это не похоже, так как типизирующие и диспетчерские концепции обоих языков фундаментальны, поэтому ничто не может быть похоже на другое. Однако, …

    Тогда мы должны отличаться друг от друга «двумя сторонами».

    A. Использование

    Когда вы используете его в сообщении, это просто ссылка на объект как любая другая:

     [self doSomething]; [anotherObject doSomething]; 

    Технически обе линии работают одинаково (например, прием другого приемника). Это особенно означает, что первая строка не приводит к выполнению метода внутри classа self , потому что self не обязательно относится к «этому classу». Поскольку каждое сообщение внутри Objective-C (единственное исключение: сообщения для super ) может привести к выполнению метода в подclassе:

     @interface A : NSObject - (void)doSomething; - (void)doAnotherThing; @end @implementation - (void)doSomething { [self doAntoherThing]; } - (void)doAnotherThing { NSLog( @"A" ); } @interface B : A - (void)doSomething; // Not necessary, simply as a marker @end @implementation B - (void)doAnotherThing { NSLog( @"B" ); } 

    В коде, подобном этому

     B *b = [B new;] [b doSomething]; 

    Линия

      [self doAnotherThing]; 

    в classе A приведет к выполнению -doAnotherThing ( B ), потому что сообщения для self -doAnotherThing как каждое другое сообщение. Результат на консоли будет b “B”, а не “A”. Используя « self в качестве приемника, вы не должны думать ни о каком отдельном правиле. Их совершенно нет.

    (И приведенный выше пример – очень хороший пример использования методов self в classе, поскольку такая же ситуация может возникать в методах classа. Использование самого classа ломает polymorphism, что является одной из худших идей в ООП. class методы тоже).

    B. Получение self

    На что указывает я? Он указывает на объект, которому отправлено сообщение, вызвавшее выполнение текущего метода.

    Имея …

     …[someObject doSomething]… // some object is a reference to an instance object 

    … как сообщение, метод называется, в самом простом случае …

     - (void)doSomething { … } 

    В этом случае self может указывать на экземпляр classа, к которому принадлежит метод. И он может указывать на экземпляр подclassа, к которому относится и метод. Вы не знаете. (И эта информация сохраняется, используя self для отправки сообщения, как описано выше).

    Если сообщение отправлено объекту classа, self указывает на объект classа, который был получателем сообщения. Это совершенно аналогично. Поэтому возможно, что self указывает на объект подclassа:

     @interface A : NSObject + (void)doSomething; + (void)doAnotherThing; @end @implementation + (void)doSomething { [self doAntoherThing]; } + (void)doAnotherThing { NSLog( @"A" ); } @interface B : A - (void)doSomething; // Not necessary, simply as a marker @end @implementation B + (void)doAnotherThing { NSLog( @"B" ); } 

    Имея эти classы

     …[A doSomething]… 

    self inside -doSomething ( A ) указывает на объект classа B Поэтому [self doAnotherThing] of B (!). Это явно отличается от

     + (void)doSomething { [A doAntoherThing]; } 

    Последняя версия наносит вред принципам ООП.

    В качестве побочного примечания возможно, что внутри внутри classа метод корневого classа указывает на экземпляр объекта корневого classа или любого подclassа. Вы должны помнить об этом при написании категорий в NSObject .

    self – это указатель объекта на таблицу рассылки текущих экземпляров. Это неявный первый аргумент для каждой функции-члена объекта и назначается при вызове этой функции.

    В таких функциях, как init, вам нужно быть осторожным, что при вызове суперclassа init вы переназначаете себя как возвращаемое значение, поскольку суперclass init может переопределить то, что указывает на себя.

    super похож на сам, за исключением того, что он указывает на таблицу диспетчера суперclassа.

    Давайте будем гением компьютера.