关联对象与属性与实例变量之间的区别
Difference between Associate Objects vs Properties vs Instance Variable
我一直在深入研究一些 Objective C 运行时方法,想知道关联对象和属性之间有什么区别。
我最感兴趣的是它们的底层实现和 pros/cons 动态使用其中一个,如果一个调用另一个,或者它们是否以任何方式相互关联。
这些是添加每个的三个运行时方法:
class_addProperty (Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount)
对比
objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy).
对
class_addIvar(Class cls, const char *name, size_t size, uint8_t alignment, const char *types)
想到的直接答案是它们完全不同,但我明白为什么有人会混淆。
属性
在 OOP 中,一般来说,属性 是 实例 [=] 的 方法 82=] 提供 接口 读取 and/or 写入特定数据成员。
在Objective-C中,@syntheisze
指令用于指示编译器创建或指定方法来获取and/or设置class实例的一些数据成员.这些方法本身通常称为“吸气剂”和“setters。”
要记住的重要一点是属性是美化的方法。
另一方面,实际变量在物理上被赋予space(内存)来存储它们的数据。假设我们有一个 class NSPerson:
@interface NSPerson : NSObject
@property (nonatomic, copy, readwrite) NSString *chosenName;
@property (nonatomic, copy, readonly) NSString *givenName;
@property (nonatomic, copy, readonly) NSString *fullName;
@end
@implementation NSPerson
@synthesize chosenName = _chosenName, givenName = _givenName
- (NSString *)fullName {
return [NSString stringWithFormat:@"%@ %@", self.chosenName, self.givenName];
}
@end
在这种情况下,@synthesize
指令执行以下操作:
- 创建一个名为
_chosenName
的变量
- 创建一个方法
- (NSString *)chosenName
returns _chosenName
- 创建方法
- (void)setChosenName:(NSString *)chosenName
将 _chosenName
设置为输入
- 为
givenName
做与上面相同的三件事
- 对
fullName
没有任何作用
现在,fullName
不需要自己的内存,因为它没有什么可存储的。出于同样的原因,它也不需要 setter 。因为它是只读的,而且我们已经明确提供了 fullName
的 实现 ,所以我们完成了 - fullName
是一个非常好的 属性 因为这是一种方法 1) 不接受任何参数,并且 2) 吐出预期的类型。
关联对象
虽然属性几乎是所有主要 OOP 语言的一部分,但 Apple 提供的形式的关联对象对于 Objective-C 来说是相当独特的。
一个更好的问题应该是:字段(或实例变量)和关联对象?
字段和关联对象都保存数据 - 不像 methods/properties,它只是 return
数据 - 两者都可以绑定到特定实例。
我认为关联对象的方式是通过类比的方式。您之前可能处理过一些 JSON。 JSON 对象如下所示:
var data = {
balance: 15.04,
mood: 'hungry',
friends: [
'larry',
'momed',
'zeus',
]
}
现在,每个键:例如 balance
都与一个值配对。在这个类比中,键是实例变量。
关联对象可能在哪里?
var associated = {};
var assc = associated[data] = {}; // the INSTANCE data is the KEY of the ASSOCIATIVE ARRAY
assc.extrra = "peekaboo";
我意识到这不是一个完美的类比,但我希望它能说明上面的 associated
就像允许关联对象的 Objective-C 运行时的实现 - 以及关联的对象对象是变量而不是方法。
编辑:为什么关联对象?
我 运行 没气了,但我想提一下,关联对象的主要用途是 back categories[=82] 中的属性=] 和 extensions 不能使用传统字段存储数据。这是两者之间关于 Objective-C.
的通常联系
我一直在深入研究一些 Objective C 运行时方法,想知道关联对象和属性之间有什么区别。
我最感兴趣的是它们的底层实现和 pros/cons 动态使用其中一个,如果一个调用另一个,或者它们是否以任何方式相互关联。
这些是添加每个的三个运行时方法:
class_addProperty (Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount)
对比
objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy).
对
class_addIvar(Class cls, const char *name, size_t size, uint8_t alignment, const char *types)
想到的直接答案是它们完全不同,但我明白为什么有人会混淆。
属性
在 OOP 中,一般来说,属性 是 实例 [=] 的 方法 82=] 提供 接口 读取 and/or 写入特定数据成员。
在Objective-C中,@syntheisze
指令用于指示编译器创建或指定方法来获取and/or设置class实例的一些数据成员.这些方法本身通常称为“吸气剂”和“setters。”
要记住的重要一点是属性是美化的方法。
另一方面,实际变量在物理上被赋予space(内存)来存储它们的数据。假设我们有一个 class NSPerson:
@interface NSPerson : NSObject
@property (nonatomic, copy, readwrite) NSString *chosenName;
@property (nonatomic, copy, readonly) NSString *givenName;
@property (nonatomic, copy, readonly) NSString *fullName;
@end
@implementation NSPerson
@synthesize chosenName = _chosenName, givenName = _givenName
- (NSString *)fullName {
return [NSString stringWithFormat:@"%@ %@", self.chosenName, self.givenName];
}
@end
在这种情况下,@synthesize
指令执行以下操作:
- 创建一个名为
_chosenName
的变量
- 创建一个方法
- (NSString *)chosenName
returns_chosenName
- 创建方法
- (void)setChosenName:(NSString *)chosenName
将_chosenName
设置为输入 - 为
givenName
做与上面相同的三件事
- 对
fullName
没有任何作用
现在,fullName
不需要自己的内存,因为它没有什么可存储的。出于同样的原因,它也不需要 setter 。因为它是只读的,而且我们已经明确提供了 fullName
的 实现 ,所以我们完成了 - fullName
是一个非常好的 属性 因为这是一种方法 1) 不接受任何参数,并且 2) 吐出预期的类型。
关联对象
虽然属性几乎是所有主要 OOP 语言的一部分,但 Apple 提供的形式的关联对象对于 Objective-C 来说是相当独特的。
一个更好的问题应该是:字段(或实例变量)和关联对象?
字段和关联对象都保存数据 - 不像 methods/properties,它只是 return
数据 - 两者都可以绑定到特定实例。
我认为关联对象的方式是通过类比的方式。您之前可能处理过一些 JSON。 JSON 对象如下所示:
var data = {
balance: 15.04,
mood: 'hungry',
friends: [
'larry',
'momed',
'zeus',
]
}
现在,每个键:例如 balance
都与一个值配对。在这个类比中,键是实例变量。
关联对象可能在哪里?
var associated = {};
var assc = associated[data] = {}; // the INSTANCE data is the KEY of the ASSOCIATIVE ARRAY
assc.extrra = "peekaboo";
我意识到这不是一个完美的类比,但我希望它能说明上面的 associated
就像允许关联对象的 Objective-C 运行时的实现 - 以及关联的对象对象是变量而不是方法。
编辑:为什么关联对象?
我 运行 没气了,但我想提一下,关联对象的主要用途是 back categories[=82] 中的属性=] 和 extensions 不能使用传统字段存储数据。这是两者之间关于 Objective-C.
的通常联系