关联对象与属性与实例变量之间的差异

时间:2015-08-10 10:58:34

标签: ios objective-c macos objective-c-runtime objective-c-category

我一直在深入研究一些Objective C运行时方法,并想知道Associate Objects和Properties之间的区别。

我最感兴趣的是它们的底层实现和动态使用的优点/缺点,如果一个调用另一个或者它们以任何方式相互关联。

这是添加每个的三种运行时方法:

class_addProperty (Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount) 

vs

objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy).

VS

class_addIvar(Class cls, const char *name, size_t size, uint8_t alignment, const char *types)

1 个答案:

答案 0 :(得分:4)

想到的直接答案是它们完全不同,但我可以看出为什么有人会混淆。

属性

在OOP中,一般来说,属性实例方法,它提供接口读取和/或写入特定数据成员。

在Objective-C中,@syntheisze指令用于指示编译器创建或指定获取和/或设置类实例的某些数据成员的方法。这些方法本身通常称为“吸气剂”。和#34; setters。"

要记住的重要一点是,属性是美化的方法。

另一方面,实变量在物理上被赋予空间(存储器)来存储它们的数据。我们假设我们有一个班级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
  • 的方法_chosenName
  • 创建将- (void)setChosenName:(NSString *)chosenName设置为输入
  • 的方法_chosenName
  • givenName
  • 完成相同的三件事
  • fullName
  • 没有任何作用

现在,fullName不需要自己的内存,因为它没有任何内容可存储。出于同样的原因,它也不需要设定器。因为它是只读的,并且我们明确提供了fullName实现,所以我们已经完成了 - fullName是一个非常好的属性,因为它是' sa方法1)不带参数,2)吐出预期的类型。

相关对象

虽然属性几乎是所有主要OOP语言的一部分,但Apple提供的形式中的关联对象对于Objective-C来说是相当独特的。

更好的问题是:字段(或实例变量)和关联对象之间有什么区别?

字段和关联对象都保存数据 - 与方法/属性不同,只有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 属性不能使用传统字段来存储数据。这是两者之间关于Objective-C的通常联系。