美文网首页
关于objc_runtime关联对象

关于objc_runtime关联对象

作者: LikeSnooker | 来源:发表于2018-03-29 21:29 被阅读0次

关联对象,按字面理解 无非就是将两个对象关联起来。'关联'可以联想到映射,能完成这件事情的,首先想到的数据结构就是hash_map。事实上objc_runtime就是这么做的。
有了思路,我们就可以自己动手了。思路大概是这样的,我们现在要实现为一个对象去关联多个对象,这些多个对象通过不同的KEY值来存取。这样的话,一张hash表似乎是不行的。一张表只能完成一个对象到一个对象的映射。如果思路受阻,请默念下面这段话三次。

All problems in computer science can be solved by another level of indirection,
except of course for the problem of too many indirections.

一张表不行,我们可以维护这样一张表,他将每个对象映射到一张表,而映射到的表分别将不同的KEY映射到不同的对象。这样就实现了将一个对象通过不同的KEY关联到另一个对象。这里涉及 TARGET(被关联的对象) KEY(键) OBJECT(关联对象)。

typedef long TARGET;
typedef long KEY;
typedef long OBJECT;

这里全都用了long型,为什么用long型呢?(这里似乎是应该用 void *更合理嘛)。因为c++库中的hash_map需要提供两个函数对象 ,分别用来比较KEY值大小和计算KEY的哈希值(方便在hash_map中储存自定义类型)。而long型是基本类型,省去了这样的麻烦。另外就是long 在计算机中是8字节,现在大部分pc都是64位,指针也是8字节,内存模型匹配,我们可以通过类型转换来处理这个问题。是不是很讨巧呢。

typedef hash_map<TARGET,hash_map<KEY,OBJECT> > MAP;
typedef hash_map<KEY,OBJECT>             ASSOCIATION_MAP;

我们将总表的类型定义为MAP,而具体的KEY->OBJECT的映射表定义为ASSOCIATION_MAP;
好了,话不多说,直接看代码,相当简单的代码:

#include <iostream>
#include <map>
#include <ext/hash_map>

using __gnu_cxx::hash_map;
using __gnu_cxx::pair;
typedef long TARGET;
typedef long KEY;
typedef long OBJECT;
typedef hash_map<TARGET,hash_map<KEY,OBJECT> > MAP;
typedef hash_map<KEY,OBJECT>             ASSOCIATION_MAP;
typedef pair<TARGET,hash_map<KEY,OBJECT>>      TARGET_ASSOCIATIONMAP;
typedef pair<KEY,OBJECT>                       KEY_OBJECT;

class AssociationManager
{
public:
    static MAP & manager()
    {
        return AssociationManager::association;
    }
private:
    static MAP association;
private:
    AssociationManager ()
    {
        
    }
};
MAP AssociationManager::association = MAP();
OBJECT getAssociated(TARGET target,KEY key)
{
    OBJECT result = 0;
    MAP &map(AssociationManager::manager());
    MAP::iterator it = map.find(target);
    if(it != map.end())
    {
        ASSOCIATION_MAP &ass_map(it->second);
        ASSOCIATION_MAP::iterator ass_map_it = ass_map.find(key);
        if(ass_map_it != ass_map.end())
        {
            return ass_map_it->second;
        }
    }
    return result;

}
void setAssociate(TARGET target,KEY key,OBJECT objc)
{
    MAP &map(AssociationManager::manager());
    MAP::iterator it = map.find(target);
    if(it == map.end())
    {
        ASSOCIATION_MAP ass_map;
        ass_map.insert(KEY_OBJECT(key,objc));
        map.insert(TARGET_ASSOCIATIONMAP(target,ass_map));
    }
    else
    {
        (it->second).insert(KEY_OBJECT(key,objc));
    }

}
class CTarget
{
public:
    int index;
};
class CObject
{
public:
    int number;
};
int main(int argc, const char * argv[]) {
    CTarget * p_target = new CTarget;
    p_target->index    = 1;
    CObject * p_object = new CObject;
    p_object->number   = 2;
    
    static char  key[10] = "hello_map";
    // setAssociate
    setAssociate((TARGET)p_target, (KEY)key, (OBJECT)p_object);
    
    // getAssociated
    CObject * p_obj = (CObject*)getAssociated((TARGET)p_target, (KEY)key);
    
    // test
    std::cout << "关联对象.number = "<<p_obj->number << std::endl;
    std::cout << "Hello, World!\n";
    return 0;
}

我们实现了两个函数getAssociated 和setAssociate,接着我们定义了两个类,在main函数中,我们通过两个函数将两个对象关联,并随后通过第一个对象成功取出关联的对象。为了只表达出思路,代码写的十分精简,点到为止。方便阅读。当然objc_runtime在实现的时候,还需要考虑到存取策略等一些列的问题。

相关文章

  • 关于objc_runtime关联对象

    关联对象,按字面理解 无非就是将两个对象关联起来。'关联'可以联想到映射,能完成这件事情的,首先想到的数据结构就是...

  • iOS runtime 关联对象

    关联对象 Associated Object 顾名思义,就是把一个对象关联到另外一个对象身上。 关于关联对象,ru...

  • 关联对象底层结构

    关联对象的方法 runtime给我们提供了三个关于关联对象的方法,如下。点击查看如何添加关联对象[https://...

  • objc_runtime关联(objc_setAssociate

    我们刚学习OC的时候知道类目是不可以添加属性的,其实这不是绝对的,我们可以通过objc_setAssociated...

  • 关于分类(Category)关联对象的一些了解

    本文是关于Category关联对象的一些理解化,以及部分使用建议。仅适用于新手玩家(对Category关联对象停留...

  • Swift 为分类增加属性objc_getAssociated

    OC 获取关联对象 Swift 获取关联对象——错误的写法 Swift 获取关联对象——正确的写法 设置关联对象 ...

  • iOS runtime关联对象 objc_setAssociat

    关联对象的作用: 关联对象可以给某个对象关联一个或者多个其他对象,这些对象通过健来区分。 创建存储关联对象objc...

  • 关联对象

    关联对象的方式 关联对象源码基本思路 关联对象的结构:AssociationsHashManager // Ass...

  • 关联对象

    关联对象原理 关联对象并不是存储在被关联对象本身内存中,关联对象存储在全局的统一的一个AssociationsMa...

  • 关联对象存放自定义数据

    关联对象存放自定义数据 关于objc_setAssociatedObject和objc_getAssociated...

网友评论

      本文标题:关于objc_runtime关联对象

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