Разница между объявлением @interface и объявлением @property - PullRequest
29 голосов
/ 29 января 2010

Я новичок в C, плохо знаком с целью C. Для подкласса iPhone я объявляю переменные, которые я хочу видеть всеми методами в классе в определении класса @interface, например,

@interface myclass : UIImageView {
    int aVar;
}

и затем я снова объявляю это как

@property int aVar;

А потом я

@synthesize aVar;

Можете ли вы помочь мне понять цель трех шагов? Я делаю что-то ненужное?

Спасибо.

Ответы [ 6 ]

57 голосов
/ 29 января 2010

Здесь вы объявляете переменную экземпляра с именем aVar:

@interface myclass : UIImageView {
    int aVar;
}

Теперь вы можете использовать эту переменную в вашем классе:

aVar = 42;
NSLog(@"The Answer is %i.", aVar);

Однако переменные экземпляра являются частными в Objective-C. Что если вам нужны другие классы для доступа и / или изменения aVar? Поскольку методы являются общедоступными в Objective-C, ответ заключается в написании метода доступа (getter), который возвращает aVar, и метода мутатора (setter), который устанавливает aVar:

// In header (.h) file

- (int)aVar;
- (void)setAVar:(int)newAVar;

// In implementation (.m) file

- (int)aVar {
    return aVar;
}

- (void)setAVar:(int)newAVar {
    if (aVar != newAVar) {
        aVar = newAVar;
    }
}

Теперь другие классы могут получить и установить aVar через:

[myclass aVar];
[myclass setAVar:24];

Написание этих методов доступа и мутатора может быть довольно утомительным, поэтому в Objective-C 2.0 Apple упростила его для нас. Теперь мы можем написать:

// In header (.h) file

@property (nonatomic, assign) int aVar;

// In implementation (.m) file

@synthesize aVar;

... и методы accessor / mutator будут автоматически сгенерированы для нас.

Подводя итог:

  • int aVar; объявляет переменную экземпляра aVar

  • @property (nonatomic, assign) int aVar; объявляет методы доступа и мутатора для aVar

  • @synthesize aVar; реализует методы доступа и мутатора для aVar

12 голосов
/ 29 января 2010

Это объявляет переменную экземпляра в вашем объекте:

@interface myclass : UIImageView {
    int aVar;
}

Переменные экземпляра являются частными деталями реализации вашего класса.

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

@property int aVar;

Это означает, что компилятор ожидает увидеть методы доступа метода set и get для свойства.

Когда вы используете ключевое слово @synthesize, вы просите компилятор автоматически сгенерировать для вас методы доступа для методов set и get.

Итак, в этом случае компилятор сгенерирует код, подобный этому, когда встретит ключевое слово @synthesize:

- (int) aVar
{
    return aVar;
}

- (void)setAVar:(int)someInt
{
    aVar = someInt;
}

По умолчанию на iPhone (и в 32-разрядной среде выполнения на Mac), @synthesize требует наличия переменной экземпляра для хранения значения свойства. Этот ivar обычно называется таким же, как свойство, но не обязательно, например, вы можете сделать это:

@interface myclass : UIImageView {
    int aVar;
}

@property int someValue;

@synthesize someValue = aVar;

На самом деле @synthesize и @property не требуются, вы можете создавать свои собственные методы получения и установки, и до тех пор, пока вы создаете их с использованием синтаксиса, совместимого с Key-Value Coding, свойство все равно будет использоваться.

Требование присутствия ивара, а также объявление @property связано с ограничением хрупкого базового класса 32-разрядной среды выполнения Objective C как на Mac, так и на iPhone. С 64-битной средой исполнения на Mac вам не нужен ивар, @synthesize генерирует его для вас.

Обратите внимание, что есть множество ключевых слов, которые вы можете использовать с объявлением @property для управления типом синтезированного кода доступа, например, readonly для средства доступа только для получения, copy, atomic, nonatomic и тд. Более подробная информация содержится в документации по Objective-C 2.0 .

1 голос
/ 29 января 2010

Классы могут иметь переменные экземпляра (ivars). Они находятся в первом разделе и видны только коду в этом классе, а не внешнему коду. Мне нравится ставить перед ними подчеркивание, чтобы показать их внутренность. В терминах низкого уровня, ivars добавляются в качестве дополнительного члена к структуре, которую класс, который вы создаете, использует внутри себя.

Второе объявление, @property, является объявленным свойством. Это не требуется (кроме случаев, когда вы используете @synthesize), но это помогает другим программистам (и компилятору!) Знать, что вы имеете дело со свойством, а не только с двумя методами -setAVar и -aVar, которые являются альтернативный способ сделать это.

В-третьих, @synthesize фактически создает методы для установки и доступа к свойству извне класса. Вы можете заменить это своими собственными методами set и getter, но делайте это только в случае необходимости, поскольку встроенные имеют некоторые функции, которые в противном случае вам пришлось бы кодировать самостоятельно. Фактически, используя синтаксис @synthesize aVar = _someVariable;, вы можете сделать так, чтобы ваше свойство ссылалось на переменную экземпляра с другим именем!

Короткая версия: @Property - это просто подсказка компилятору и другим программистам, что вы создаете свойство, а не только методы getter / setter. Переменные экземпляра являются внутренними для класса и, в противном случае, не могут быть доступны извне. @Synthesize просто создает для вас простые методы получения и установки для использования с @property, но вы также можете просто кодировать эти методы получения и установки самостоятельно, как любой другой метод.

0 голосов
/ 29 мая 2013
Class A      

      @interface myclass : UIImageView {
    int aVar;
}

If you declare like this then you can only use this variable within your class A.


But suppose in Class B

    A *object=[A new];
object.aVar---->not available



For this you should **declare aVar as a property in Class A**

so class A should look like 

Class A      

  @interface myclass : UIImageView {
    int aVar;
}
@property int iVar;


and 


.m file 
@synthesize iVar;



So now you can use this iVar in another class Suppose B


 Class B
#import "Class A.h"

    enter code here

A *object=[A new];
object.aVar---->available
means
object.aVar=10;
0 голосов
/ 25 января 2012

Я недавно начал изучать приложения для iphone. Насколько мне известно, @property используется в .h файле в качестве метода установки, а @synthesize в .m файле - в качестве метода получения. В Java мы используем методы setter и getter, так же как и Java, в Objective C мы используем @property и @ synthesize.

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

0 голосов
/ 29 января 2010

@ interface объявляет переменные экземпляров класса в obj-c. Вам это нужно для создания переменной экземпляра. Однако переменная по умолчанию не видна вне класса (так как поле по умолчанию защищено).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...