美文网首页
关联对象 AssociatedObject

关联对象 AssociatedObject

作者: 有一种再见叫青春 | 来源:发表于2016-12-09 11:24 被阅读29次

主要包含两个方面内容:

<li>使用关联对象为已经存在的类添加属性</li>
<li>关联对象在底层OC中的实现</li>


@property可以说是一个 Objective-C 编程中的“宏”,它有元编程的思想。
<pre>`

@interface Property : NSObject
/** ProPerty */
@property (nonatomic, strong)NSString * property;
@end</pre> 在声明属性时上述代码做了如下3件事: <ul> <li>生成实例变量_property</li> <li>生成 getter方法- property</li> <li>生成 setter方法- setProperty:</li> </ul> <pre>@implementation Property {
NSString *_property;
}

  • (NSString *)property {
    return _property;
    }

  • (void)setProperty:(NSString *)property {
    _property = property;
    }

@end

`</pre>

以上代码都是编译器自动生成隐藏在内部的,那么为什么在分类中不能声明属性?
我们知道,在 Objective-C 中可以通过 Category 给一个现有的类添加属性,但是却不能添加实例变量,这似乎成为了 Objective-C 的一个明显短板。然而值得庆幸的是,我们可以通过 Associated Objects 来弥补这一不足。

相关函数

与Associated Objects相关的函数主要有3个,我们可以在 runtime 源码的 runtime.h 文件中找到它们的声明:
<pre>void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy); id objc_getAssociatedObject(id object, const void *key); void objc_removeAssociatedObjects(id object);</pre>

这三个函数的命名对程序员非常友好,可以让我们一眼就看出函数的作用:
objc_setAssociatedObject
用于给对象添加关联对象,传入 nil
则可以移除已有的关联对象;
objc_getAssociatedObject
用于获取关联对象;
objc_removeAssociatedObjects
用于移除一个对象的所有关联对象。

:objc_removeAssociatedObjects
函数我们一般是用不上的,因为这个函数会移除一个对象的所有关联对象,将该对象恢复成“原始”状态。这样做就很有可能把别人添加的关联对象也一并移除,这并不是我们所希望的。所以一般的做法是通过给 objc_setAssociatedObject
函数传入 nil
来移除某个已有的关联对象。

key 值

关于前两个函数中的 key
值是我们需要重点关注的一个点,这个 key值必须保证是一个对象级别(为什么是对象级别?看完下面的章节你就会明白了)的唯一常量。一般来说,有以下三种推荐的 key 值:
声明 static char kAssociatedObjectKey,使用 &kAssociatedObjectKey 作为 key值;
声明 static void *kAssociatedObjectKey = &kAssociatedObjectKey;,使用 kAssociatedObjectKey
作为 key 值;
用 selector ,使用getter 方法的名称作为 key值。

objc_setAssociatedObject

我们可以在 objc-references.mm文件中找到 objc_setAssociatedObject 函数最终调用的函数:

<pre>`
void _object_set_associative_reference(id object, void *key, id value, uintptr_t policy) {
// retain the new value (if any) outside the lock.
ObjcAssociation old_association(0, nil);
id new_value = value ? acquireValue(value, policy) : nil;
{
AssociationsManager manager;
AssociationsHashMap &associations(manager.associations());
disguised_ptr_t disguised_object = DISGUISE(object);
if (new_value) {
// break any existing association.
AssociationsHashMap::iterator i = associations.find(disguised_object);
if (i != associations.end()) {
// secondary table exists
ObjectAssociationMap refs = i->second;
ObjectAssociationMap::iterator j = refs->find(key);
if (j != refs->end()) {
old_association = j->second;
j->second = ObjcAssociation(policy, new_value);
} else {
(
refs)[key] = ObjcAssociation(policy, new_value);
}
} else {
// create the new association (first time).
ObjectAssociationMap refs = new ObjectAssociationMap;
associations[disguised_object] = refs;
(
refs)[key] = ObjcAssociation(policy, new_value);
object->setHasAssociatedObjects();
}
} else {
// setting the association to nil breaks the association.
AssociationsHashMap::iterator i = associations.find(disguised_object);
if (i != associations.end()) {
ObjectAssociationMap *refs = i->second;
ObjectAssociationMap::iterator j = refs->find(key);
if (j != refs->end()) {
old_association = j->second;
refs->erase(j);
}
}
}
}
// release the old value (outside of the lock).
if (old_association.hasValue()) ReleaseValue()(old_association);
}

`</pre>

参考资料链接:
http://blog.leichunfeng.com/blog/2015/06/26/objective-c-associated-objects-implementation-principle/

相关文章

  • 关联对象 AssociatedObject

    主要包含两个方面内容: 使用关联对象为已经存在的类添加属性 关联对象在底层OC中的实现 @property可以说...

  • AssociatedObject关联对象

    基本用法 以下是几种不同key的写法 关联对象的原理 关联对象不是存储在对象本身的内存中的,它被保存在一个全局的A...

  • iOS 基础知识之关联对象

    简介 associatedObject又称关联对象,把一个对象关联到另外一个对象身上,使两者能够产生联系。关联对象...

  • 关于iOS Class Category的整理

    参考 Category官方指导文档 关联对象 AssociatedObject 完全解析 深入理解Objectiv...

  • 探索AssociatedObject关联对象的内部实现

    AssociatedObject关联对象 为什么要引入关联对象? 一般我们需要对现有的类做扩展,可以通过继承、类别...

  • 【iOS】关联对象详解

    前言 associatedObject又称关联对象。顾名思义,就是把一个对象关联到另外一个对象身上。使两者能够产生...

  • 【iOS】关联对象详解

    前言 associatedObject又称关联对象。顾名思义,就是把一个对象关联到另外一个对象身上。使两者能够产生...

  • 分类-关联对象

    给分类添加成员变量 另一篇:关联对象 AssociatedObject 完全解析.h .m 在其他实例中调用 关联...

  • OC-关联对象AssociatedObject

    关联对象 前言 我们都知道ARC环境下, 在一个类中声明一个属性@property (nonatomic, ass...

  • AssociatedObject关联对象原理实现

    介绍 关联对象(AssociatedObject)是Objective-C 2.0运行时的一个特性,允许开发者对已...

网友评论

      本文标题:关联对象 AssociatedObject

      本文链接:https://www.haomeiwen.com/subject/rqsmuttx.html