Разница между объявлением ивара в @interface и помещением переменной в @implementation - PullRequest
7 голосов
/ 06 апреля 2011

В чем разница между объявлением ивара в @interface и помещением переменной в @implementation в файле .m?

@interface MyClass : NSObject {
  int num;
}
- (void)doSomething;
@end

против

@implementation MyClass   
int num2;

- (void)doSomething {
  num = 137;
  num2 = 138;
}
@end

Есть ли когда-нибудь время, когда вы хотите поместить переменную в @implementation?

Ответы [ 3 ]

8 голосов
/ 06 апреля 2011

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

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

Обновление 4/17/14

Обычной практикой является использование Свойства . Это создает методы получения и установки для вас автоматически, делая класс более расширяемым (если вы решите изменить способ работы свойства, возможно, вы захотите изменить его так, чтобы он всегда вычислялся на лету, открытый интерфейс класса изменять не нужно) ).

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

5 голосов
/ 06 апреля 2011

Насколько я знаю, размещение объявления переменной внутри @implementation ничем не отличается от ее размещения вне реализации: это не ivar, это просто переменная, объявленная в области видимости файла.

Одно из примененийдля объявления эквивалента статических членов C ++.Например:

@implementation MyClass

static int s_count = 0;

- (id)init {
  if ((self = [super init]))
    ++s_count;
  return self;
}

- (void)dealloc {
  --s_count;
  [super dealloc];
}

Если предположить, что init является вашим единственным инициализатором, тогда s_count будет содержать общее количество активных MyClass экземпляров.

1 голос
/ 05 августа 2012

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

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

( source )

...