Есть ли разница между «переменной экземпляра» и «свойством» в Objective-c?
Я не очень в этом уверен. Я думаю, что «свойство» - это переменная экземпляра, у которой есть методы доступа, но я могу ошибаться.
источник
Есть ли разница между «переменной экземпляра» и «свойством» в Objective-c?
Я не очень в этом уверен. Я думаю, что «свойство» - это переменная экземпляра, у которой есть методы доступа, но я могу ошибаться.
Свойство - это более абстрактное понятие. Переменная экземпляра - это буквально просто слот для хранения, как слот в структуре. Обычно другие объекты никогда не должны обращаться к ним напрямую. С другой стороны, свойство - это атрибут вашего объекта, к которому можно получить доступ (это звучит расплывчато, и так должно быть). Обычно свойство возвращает или устанавливает переменную экземпляра, но оно может использовать данные из нескольких или вообще ни одного. Например:
@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
(Примечание: приведенный выше код ошибочен, поскольку предполагает, что имя уже существует и имеет как минимум два компонента (например, «Билл Гейтс», а не просто «Гейтс»). Я чувствовал, что исправление этих предположений сделает реальную суть кода менее ясно, поэтому я просто указываю на это здесь, чтобы никто невинно не повторил эти ошибки.)
Свойство - это удобный способ реализации получателя / установщика некоторого значения с дополнительными полезными функциями и синтаксисом. Свойство может поддерживаться переменной экземпляра, но вы также можете определить геттер / сеттер, чтобы делать что-то более динамичное, например, вы можете определить свойство 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
вызовы get / set соответствующими блокировками, чтобы предотвратить проблемы параллелизма. Вы можете указатьnonatomic
атрибут, чтобы отключить это (например, на iPhone вы хотите установить большинство свойств по умолчаниюnonatomic
).Есть 3 значения атрибута, которые контролируют управление памятью для любых
@synthesized
установщиков. Первый изretain
них автоматически отправляетrelease
старые значения свойства иretain
новые значения. Это очень полезно.Второй -
copy
это копирование любых переданных значений, а не их сохранение. Рекомендуется использоватьcopy
для NSString, потому что вызывающий может передать NSMutableString и изменить его из-под вас.copy
создаст новую копию ввода, доступ к которой есть только у вас.Третий -
assign
это назначение прямого указателя без вызова функции сохранения / освобождения для старого или нового объекта.Наконец, вы также можете использовать
readonly
атрибут, чтобы отключить сеттер для свойства.источник
Я использую свойства для интерфейсной части - где объекты взаимодействуют с другими объектами, а переменные экземпляра - это вещи, которые вам нужны внутри вашего класса - никто, кроме вас, не должен их видеть и манипулировать ими.
источник
По умолчанию свойство readwrite будет поддерживаться переменной экземпляра, которая снова будет автоматически синтезирована компилятором.
Переменная экземпляра - это переменная, которая существует и хранит свое значение в течение всего срока службы объекта. Память, используемая для переменных экземпляра, выделяется при первом создании объекта (посредством выделения) и освобождается при освобождении объекта.
Если не указано иное, синтезированная переменная экземпляра имеет то же имя, что и свойство, но с префиксом подчеркивания. Например, для свойства с именем firstName синтезированная переменная экземпляра будет называться _firstName.
источник
Раньше люди использовали свойства публично, а ivars - для личного использования, но несколько лет назад вы также можете определять свойства,
@implementation
чтобы использовать их в частном порядке. Но я бы по-прежнему использовал ivars, когда это возможно, поскольку нужно вводить меньше букв, и, согласно этой статье , он работает быстрее . Это имеет смысл, поскольку свойства подразумеваются как «тяжелые»: предполагается, что к ним можно обращаться либо из сгенерированных геттеров / сеттеров, либо из тех, что написаны вручную.Однако в последних кодах от Apple ivars больше не используются. Я думаю , потому что это больше похоже
objc
, чемC/C++
, плюс это легче использовать свойство сassign
,nullable
и т.д.источник
@implementation
хочет показать сходство со Swift. Тем не менее, я также предпочитаю резервные переменные, чтобы не тратить зря вызов виртуальной функции для поиска простого поля моего собственного класса (и это происходит при доступе к свойству).