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

Разница между self.ivar и ivar?

aclass.h

@interface aClass : NSObject {
    NSString *name;
}

@property (nonatomic, retain) IBOutlet NSString *name;

@end

aclass.m 

@implementation aClass

@synthesize name;

- (void)dealloc {
    [name release];
    [super dealloc];    
}

- (void)test1 {
    name = @"hello";
}

- (void)test2 {
    self.name = @"hello";
}

В качестве примера возьмем выше. Может ли кто-нибудь объяснить разницу между name = @"hello" и self.name = @"hello"? Спасибо!

EDIT: следующий вопрос: Как написать свой собственный сеттер для ivar, т.е.: self.ivar =...?

4b9b3361

Ответ 1

ЗАРЕГИСТРИРУЙТЕ, ЭТО ПОЧТА СТАРО!

Это сообщение от предыдущего десятилетия.

Обязательно прочитайте важную сноску внизу, приветствуйте!


Это очень сложно понять, когда вы только начинаете.

Вот несколько простых, ПРАКТИЧЕСКИХ правил большого пальца ДЛЯ НАЧИННИКОВ.

Чтобы повторить, этот пост ДЛЯ НАЧИННИКОВ.

Цель состоит в том, чтобы позволить вам быстро перейти от стартовой линии к возможности уверенно использовать систему в большинстве ситуаций.

Позже, вы можете действительно узнать о внутренней работе этих проблем.

(1) Никогда не говори [email protected]"hello". Всегда говорите [email protected]"hello". Сделайте поиск по всему тесту name и убедитесь, что вы всегда говорите self.name, а не name, когда вы его устанавливаете или изменяете.

(2) Вы знаете все, что приводит в бешенство информацию об управлении памятью, инициализации, выпуске и т.д. Если вы используете self thingy, , он заботится обо всем этом для вас. Прохладный ха?

(3) Самопомощь особенно полезна, потому что вы можете легко "изменить" строку (или что бы то ни было) по мере продвижения. Итак, это полностью ОК, чтобы сделать это,

[email protected]"aa";  
[email protected]"bb";  
[email protected]"cc";  

тогда как (словом) вы никогда не сможете, по какой-либо причине, сделать это...

[email protected]"aa";
[email protected]"bb";
[email protected]"cc";

(*) Что касается вашего буквального вопроса, "пожалуйста, объясните разницу между name = @"hello" и self.name = @"hello"?" Это легко сделать.

Первый просто устанавливает переменную. Вы знаете, точно как "x=42" в старые времена, когда жизнь была простой, и нам было 13 лет.

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

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

Еще раз, второй точно так же, как сказать...

[name bigComplicatedRoutineHere:@"hello"];

... очень полезно всегда помнить, что синтаксис self. ... буквально вызывает процедуру.

Действительно, некоторые мыслители по этой теме думали, что это была глупая идея, когда они представили этот синтаксис self.X как означающий [X complicatedThingHere]. Это вызывает много путаницы, и каждый новичок спрашивает, что именно вы спрашиваете.

Лично мне потребовалось девять лет, чтобы понять это в моей голове.:-) Итак, опять же, я подчеркиваю, что вы должны помнить, что когда вы говорите self.X, на самом деле, вы на самом деле вызываете рутину.

Повторить: синтаксис "self dot" фактически вызывает процедуру. (Действительно, я считаю, что один из препроцессоров просто расширяет его до [x amazingStuffHere].)

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

Обратите внимание, что это сообщение предназначено для советов начинающим, чтобы они продолжали идти и не становились в ярости. Надеюсь, это поможет!


2014 обновление! Важное примечание по ARC для начинающих...

Заметьте, этот пост пяти лет сейчас! Это было прочитано тысячами новичков, и было много последующих вопросов и т.д. Обратите внимание, что сегодня в новом "мире ARC". В какой-то степени: если вы новичок: вы должны использовать только свойства!!. т.е. везде "везде", "везде". В любом случае, просто знайте, что информация в этом посте "во многом исторична" и становится все более и более повседневной. Конечно, само собой разумеется, что как только вы станете экспертом, вам нужно будет и понять каждую тонкую деталь всего этого. Надеюсь, это поможет кому-то.

Ответ 2

self.name использует определитель и/или мутатор, определенные вами (это неатомно и сохраняется в вашем случае). Поэтому, когда вы вызываете self.name = foo, он вызывает мутатор setName:(NSString *)str, сгенерированный компилятором, который сначала выдает текущую строку, затем сохраняет новую строку и, наконец, устанавливает имя в сохраненную строку.

Просто вызов name = foo делает не что иное, как присвоение имени foo.

Это также означает, что вы можете вызывать только self.xxx, когда вы определили свойство для ivar, иначе компилятор скажет вам, что он не знает об этом (iVar).

Ответ 3

name = @ "Joe"

Вы получаете доступ непосредственно к переменной, минуя метод getter, который Cocoa взял на себя трудность для создания для вас. Обычно это не самая мудрая вещь.

self.name = @ "Joe"

Теперь вы пройдете метод, который вы задали Cocoa, чтобы создать для вас. Обычно это лучший способ.

Как правило, всегда используйте setter и getter, предоставляемые Cocoa, с одним исключением: dealloc. В dealloc вы всегда должны отпускать переменную напрямую, а не через метод getter:

-(void) dealloc {
   [name release]; // instead of [[self name] release]
   ...

   [super dealloc];
}

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

OTOH, также есть несколько более удобный синтаксис для объявления iVars, о котором вы, возможно, не знаете. Если вы ориентируетесь только на 64-битные маки, вы можете использовать свойства для генерации как методов доступа, так и самой переменной экземпляра:

#import <Cocoa/Cocoa.h>
@interface Photo : NSObject 
@property (retain) NSString* caption; 
@property (retain) NSString* photographer; 
@end

Ответ 4

Это реальное управление памятью, поскольку грамматика свойств - это реальный метод setter и getter, когда используется self.xxx =?, он может вызвать метод setter, объект сохраняет cout +1, имя не может быть выпущено, однако если имя = foo не имеет ничего общего с грамматикой свойств.

пример метода сеттера:

-(void)setObj:(ClassX*) value 
{  
         if (obj != value) 
         { 
                   [obj release]; 
                   obj = [value retain]; 
         } 
}