Есть ли разница между «переменной экземпляра» и «свойством» в Objective-c? - PullRequest
79 голосов
/ 09 мая 2009

Есть ли разница между "переменной экземпляра" и "свойством" в Objective-c?

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

Ответы [ 5 ]

81 голосов
/ 09 мая 2009

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

@interface Person : NSObject {
    NSString *name;
}

    @property(copy) NSString *name;
    @property(copy) NSString *firstName;
    @property(copy) NSString *lastName;
@end

@implementation Person
    @synthesize name;

    - (NSString *)firstName {
        [[name componentsSeparatedByString:@" "] objectAtIndex:0];
    }
    - (NSString *)lastName {
        [[name componentsSeparatedByString:@" "] lastObject];
    }
    - (NSString *)setFirstName:(NSString *)newName {
        NSArray *nameArray = [name componentsSeparatedByString:@" "];
        NSArray *newNameArray [[NSArray arrayWithObjects:newName, nil] arrayByAddingObjectsFromArray:[nameArray subarrayWithRange:NSMakeRange(1, [nameArray size]-1)]];
        self.name = [newNameArray componentsJoinedByString:@" "];
    }
    - (NSString *)setLastName:(NSString *)newName {
        NSArray *nameArray = [name componentsSeparatedByString:@" "];
        NSArray *newNameArray [[nameArray subarrayWithRange:NSMakeRange(0, [nameArray size]-2)] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:newName, nil]];
        self.name = [newNameArray componentsJoinedByString:@" "];
    }
@end

(Примечание. Приведенный выше код содержит ошибки, так как предполагает, что имя уже существует и содержит как минимум два компонента (например, «Билл Гейтс», а не просто «Гейтс»). Я чувствовал, что исправление этих предположений сделает фактическую точку кода менее понятным, поэтому я просто указываю на это, чтобы никто не повторял эти ошибки.)

31 голосов
/ 09 мая 2009

Свойство - это удобный способ реализации метода получения / установки для некоторого значения с дополнительными полезными функциями и синтаксисом. Свойство может быть поддержано переменной экземпляра, но вы также можете определить метод получения / установки, чтобы сделать что-то более динамичное, например, Вы можете определить свойство lowerCase для строки, которая динамически создает результат, а не возвращает значение некоторой переменной-члена.

Вот пример:

// === In your .h ===

@interface MyObject {
    NSString *propertyName;

}

// ...

@property (nonatomic, retain) NSString *propertyName;

// === In your .m @implementation ===

@synthesize propertyName /* = otherVarName */;

Строка @property определяет свойство с именем propertyName типа NSString *. Это можно получить / установить, используя следующий синтаксис:

myObject.propertyName = @"Hello World!";
NSLog("Value: %@", myObject.propertyName);

Когда вы присваиваете или читаете из myObject.propertyName, вы действительно вызываете методы установки / получения для объекта.

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

Наряду с @synthesize вы все равно можете переопределить один из методов получения / установки, определив свой собственный. Соглашение об именах для этих методов: setPropertyName: для установщика и propertyName (или getPropertyName, не стандартное) для получателя. Другое все равно будет сгенерировано для вас.

В вашей строке @property вы можете определить количество атрибутов в скобках для свойства, которое может автоматизировать такие вещи, как безопасность потоков и управление памятью. По умолчанию свойство является атомарным, то есть компилятор обернет @synthesiz ed вызовы get / set соответствующими блокировками для предотвращения проблем параллелизма. Вы можете указать атрибут nonatomic, чтобы отключить это (например, на iPhone вы хотите, чтобы большинство свойств по умолчанию были nonatomic).

Существует 3 значения атрибута, которые управляют управлением памятью для любых @synthesized сеттеров. Первый - retain, который автоматически отправит release старым значениям свойства и retain новым значениям. Это очень полезно.

Вторым является copy, который будет копировать любые переданные значения, а не сохранять их. Рекомендуется использовать copy для NSString, потому что вызывающая сторона может передать NSMutableString и изменить его из-под вас. copy создаст новую копию ввода, к которой имеют доступ только вы.

Третий - assign, который выполняет прямое назначение указателя без вызова сохранения / освобождения старого или нового объекта.

Наконец, вы также можете использовать атрибут readonly, чтобы отключить установщик для свойства.

6 голосов
/ 15 июня 2013

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

3 голосов
/ 28 мая 2016

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

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

Если не указано иное, синтезированная переменная экземпляра имеет то же имя, что и свойство, но с префиксом подчеркивания. Например, для свойства с именем firstName синтезированная переменная экземпляра будет называться _firstName.

1 голос
/ 07 июня 2016

Ранее люди использовали свойства публично и ivars для личного пользования, но с тех пор, как несколько лет назад, вы также можете определить свойства в @implementation, чтобы использовать их в частном порядке. Но я бы по-прежнему использовал ivars, когда это возможно, поскольку букв меньше набирается, и он работает быстрее согласно этой статье . Это имеет смысл, поскольку свойства означают быть «тяжелыми»: к ним должны обращаться либо сгенерированные методы получения / установки, либо те, которые написаны вручную.

Однако в последних кодах от Apple ивары больше не используются. Я думаю, потому что это больше похоже на objc, а не C/C++, а также проще использовать свойства с assign, nullable и т. Д.

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