Ключевое слово SELF в Objective-C

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

При инициализации экземпляра этого класса у меня есть этот метод initilize:

- (MMShowMovement *) initWithMovementName: (NSString *) name andNumber: (NSInteger) number {

 if( [super init] ) {

  [self setMovementTitle: name];
  [self setMovementNumber: number];

  [self setDotArray: [[NSMutableArray alloc] init]];

 }

 return self;

}

Позже, после создания экземпляра этого класса, я могу добавить объекты в NSMutableArray "dotArray". Вот этот метод.

- (void) addDot: (MMDot *) dot {

 [dotArray addObject: dot]; 

}

(Я знаю, это просто) Мне интересно, когда я использую "dotArray" в этом методе, я получаю доступ к объекту dotArray для экземпляра класса, для которого этот метод был вызван, правильно? Или я должен использовать здесь ключевое слово self?

- (void) addDot: (MMDot *) dot {

 [[self dotArray] addObject: dot]; 

}

Честно говоря, я не совсем уверен. Я верю, что это первое, но я не уверен, почему. И в этом методе нет необходимости использовать ключевое слово self, почему я должен использовать его в инициализаторе для доступа к объекту?

3 ответа

Решение

Обычно мы будем писать

self = [super init]  

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

Я узнал об этом ясно из книги Learn Objective-C на Mac, глава 10 "Инициализация объектов", Марка Далримпла и Скотта Кнастера, Apress.

Отрывок из книги:
Переменные экземпляра находятся в ячейке памяти, которая находится на фиксированном расстоянии от скрытого параметра self. Если новый объект возвращается из метода init, нам нужно обновить себя, чтобы любые последующие ссылки на переменные экземпляра влияли на правильные места в памяти.

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

В вашем случае это означает, что если объект типа X MMShowMovement получает addDot: само сообщение содержит указатель на X.
Вы можете получить доступ dotArray тремя разными способами:

[dotArray addObject:dot]; //directly access the instance variable dotArray
[[self dotArray] addObject:dot]; //access dotArray with an accessor method
//--or--
[self.dotArray addObject:dot]; //access dotArray with an accessor method using dot-syntax

Если вы используете автоматические уведомления KVO, вы должны использовать средства доступа (вместо прямого манипулирования ivar) для запуска уведомлений.
Чтобы убедиться, что переменная доступна через метод доступа, вы должны поставить префикс self.

[self dotArray] вызывает "dotArray" селектор (метод) объекта. Если такого метода нет, вы получите ошибку. Вы не можете получить доступ к переменной экземпляра таким образом, если это не свойство, и вы не синтезировали для него этот метод получения.

[dotArray addObject] просто обращается к переменной и вызывает встроенный метод, указанный в NSMutableArray.

[self setMovementTitle:], [self setMovementNumber:] и [self setDotArray:] - все это вызовы методов. Вам всегда нужна ссылка на объект для вызова метода.

В init вы также можете сказать [dotArray addObject] (после инициализации переменной, конечно).

Другие вопросы по тегам