2010-09-20 2 views
0

В чем разница между ссылкой на переменную экземпляра в Objective-C класса, как это:Различия между self.myIvar и myIvar?

self.myIvar 

и

myIvar 

, если он был объявлен как свойство в заголовке и синтезируется?

+1

Возможный дубликат [iPhone отличается между собой и нормальной переменной] (http://stackoverflow.com/questions/536388/iphone-different-between-self-and-normal-variable) – Chuck

+0

Это больше о последствиях синтезируя ivar, спасибо за ссылку, хотя, информативный. – christo16

ответ

3

Если вы обратитесь к self.myVar, он будет использовать @property, объявленный в вашем файле заголовка.

Например

@property(nonatomic, retain) Class *myClass;

Если у вас есть

myClass = [ [ Class alloc ] init .... ];

Сохранил Count будет Но если вы используете

self.myClass = [ [ Class alloc ] init .... ];

Сохранил граф будет becaus е сохраняемого свойства.

Это то же самое, если вы установили setter || метод getter в @property.

+0

Итак, при использовании self.myClass, почему счетчик удержания в 1 перед вызовом alloc/init? – christo16

+0

@christo: назначение (в сеттере) происходит после alloc/init. Вот когда количество удержаний идет до 2. Не раньше. (Операторы присваивания обычно выполняются в обратном направлении). – hotpaw2

+0

'Class *' - это указатель на указатель класса, а не указатель на экземпляр и указатель класса напрямую. Чтобы использовать такое свойство, вам нужно будет объявить переменную 'static' или instance, содержащую класс, а затем передать указатель на эту переменную в' setMyClass: 'setter:' self.myClass = & theClass'. У меня такое ощущение, что это не то, что вы имели в виду. –

0

Без себя. которую вы будете получать/присваивать фактическому члену данных класса, не проходя через getter/setter, сгенерированный @synthesize (или вы можете написать свой собственный getter/setter, если вам нужно что-то более интересное, чем поведение по умолчанию).

Обратите внимание, что в этих пользовательских аксессуарах вам почти не придется опускать себя. чтобы избежать бесконечной рекурсии, например. если у вас есть строковое свойство с именем s, сеттер может быть (это похоже на то, что генерируется, когда вы @synthesize, кстати):

-(void)setS:(NSString *)newVal 
{ 
    if(newVal == s) return; 
    [s release]; 
    s = [newVal retain]; //if you use self.s here, setS will be called again 
} 
0
self.ivar 

вызывает метод собственности, который можно позже изменить или добавить, и это может также повлиять на управление памятью. Например, вы могли бы сделать настройки self.ivar также изменить ivar2, приращение ivar3, границы проверки ivar4, отправить сообщение object5, релиз object6, играть sound7 и т.д.

ivar 

просто читает или пишет некоторое количество битов в памяти.

1

Разница заключается в том, что ivar это просто переменная, указывающая на местоположение в памяти, в то время как self.ivar вызывает метод установки (в случае self.ivar = x) и геттер (для x = self.ivar) методов. IE, под капотом, self.ivar в этих операциях преобразуется в [self setIvar:value] и [self getIvar] соответственно. Эти методы затем могут обрабатывать такие вещи, как сохранение/выпуск и любое поведение, специфичное для класса, от вашего имени, и на самом деле делают это, напрямую ссылаясь на ivar. Ключевое слово @synthesize автоматически генерирует эти методы getter и setter, чтобы вы могли сократить шаблонный код.

Таким образом, ivar - это место в памяти, где ваш объект может хранить что-то, и self.ivar обертывает методы класса в этом месте в памяти для управления доступом к нему.Обратите внимание, что при инициализации объекта обычно предпочтительнее устанавливать ivars, чтобы избежать возможного странного поведения с не полностью сформированными объектами.

3

Какая разница между ссылкой на переменную экземпляра в Objective-C класса, как это:

self.myIvar 

и

myIvar 

, если он был объявлен как свойство в заголовке ...

Простой: первый не относится к экземпляру variab ле.

Относится к объекту по имени myIvar. Аналогично, последний относится к переменной экземпляра, а не к свойству.

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

Попытка получить доступ self.myIvar точно такая же, как отправка self сообщение об утере. То есть эти два отчета:

foo = self.myIvar; 
foo = [self myIvar]; 

- это точно такие же.

Аналогичным образом, попытка присвоить self.myIvar точно такая же, как отправка self сообщения setter. Эти два утверждения:

self.myIvar = foo; 
[self setMyIvar:foo]; 

- это точно такие же.

По сравнению со ссылкой на переменную экземпляра myIvar (нет): self.

foo = myIvar; 
myIvar = foo; 

точно, что: доступ к переменной; ничего более.

Это много значит.

Аксессоры, особенно сеттер, имеют побочные эффекты. Например, если свойство объявлено как retain, синтезированный установщик для него выпустит старое значение свойства и сохранит новое значение. Аналогично, если свойство объявлено как copy, синтезированный сеттер выпустит старое значение и сделает копию нового.

С присвоения имущества:

self.myProperty = foo; 

является сообщение сбруя, , что «назначение» приведет к тому, старое значение будет выпущен и новое значение необходимо сохранить/скопировать.

Присваивание переменной:

myIvar = foo; 

будучи не более чем присвоение переменной, не будет этого делать. Если вам принадлежало старое значение myIvar, вы просто пропустили его, и если у вас еще нет нового значения, вы все равно не будете его владельцем, а это значит, что он, вероятно, умрет, пока вы все еще держитесь за него, к сбою позже. (См. the Memory Management Programming Guide.)

Несмотря на то, что два похожих друг на друга, они очень и очень разные.

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

... и синтезирован?

Это не имеет значения. @synthesize только один из трех способов рассказывания компилятора, как реализуются аксессоры отеля:

  • @synthesize: Compiler, вы их реализовать.
  • @dynamic: Не беспокойтесь об этом, компилятор; мой суперкласс будет динамически поставлять аксессуры во время выполнения. (Наиболее часто встречаются в подклассах NSManagedObject.)
  • - (Foo *) myProperty { … }/- (void) setMyProperty:(Foo *) newFoo { … }: Вот мои реализации аксессуаров.

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

Смежные вопросы