iOS - Objective-C 底层实现中的哈希表

news/2025/1/20 16:52:32/

1. 关联对象存储(AssociationsHashMap)

// 关联对象的哈希表实现
typedef DenseMap<const void *, ObjcAssociation> ObjectAssociationMap;
typedef DenseMap<DisguisedPtr<objc_object>, ObjectAssociationMap> AssociationsHashMap;class AssociationsManager {static AssociationsHashMap *_map;  // 全局关联对象表void set(id object, const void *key, id value) {// 双层 map:对象 -> (key -> value)AssociationsHashMap::iterator i = _map->find(object);if (i != _map->end()) {ObjectAssociationMap &refs = i->second;refs[key] = ObjcAssociation(value);}}
};// 特点:
// 1. 双层哈希表结构
// 2. 使用 DenseMap 实现
// 3. 支持动态扩容

注意事项:

  • 需要考虑内存开销
  • 多层查找可能影响性能
  • 需要正确管理关联对象的生命周期

2. 引用计数表(RefcountMap)

// SideTable 中的引用计数表
class SideTable {RefcountMap refcnts;  // 存储对象的引用计数void retain(id obj) {RefcountMap::iterator it = refcnts.find(obj);if (it != refcnts.end()) {it->second += SIDE_TABLE_RC_ONE;}}
};typedef objc::DenseMap<DisguisedPtr<objc_object>, size_t> RefcountMap;// 特点:
// 1. 使用 DenseMap 实现
// 2. Key 使用伪装指针
// 3. 需要频繁访问和修改

注意事项:

  • 需要保证原子性操作
  • 性能要求高
  • 内存管理要谨慎

3. 弱引用表(weak_table_t)

// 弱引用哈希表
struct weak_table_t {weak_entry_t *weak_entries;  // 哈希数组size_t num_entries;          // 实际条目数uintptr_t mask;             // 容量掩码uintptr_t max_hash_displacement; // 最大哈希偏移weak_entry_t *get(id referent) {// 使用哈希查找size_t begin = hash_pointer(referent) & mask;size_t index = begin;size_t hash_displacement = 0;while (weak_entries[index].referent != referent) {index = (index + 1) & mask;if (index == begin) break;hash_displacement++;}return &weak_entries[index];}
};// 特点:
// 1. 开放寻址法处理冲突
// 2. 使用线性探测
// 3. 记录最大偏移量

注意事项:

  • 需要控制装载因子,避免性能下降
  • 删除元素时需要特殊处理,避免破坏探测链
  • 扩容时需要重新哈希所有元素

4. 方法缓存(cache_t)

// 类的方法缓存
struct cache_t {struct bucket_t *_buckets;  // 哈希表mask_t _mask;              // 容量掩码mask_t _occupied;          // 已使用数量IMP imp(SEL sel) {// 使用哈希查找方法实现bucket_t *b = buckets();mask_t m = mask();return findMethod(b, m, sel);}
};// 特点:
// 1. 采用散列函数直接寻址
// 2. 缓存最近使用的方法
// 3. 固定大小,满了就清空重建

注意事项:

  • 缓存满时会清空重建,而不是扩容
  • 性能敏感,需要快速查找
  • 线程安全问题需要特别注意

5. 性能优化

// 使用 DenseMap 优化内存使用
template <typename T, typename U, typename V>
class DenseMap {// 1. 开放寻址法处理冲突pair<iterator, bool> insert(const T& key, const U& value) {// 查找空位置unsigned index = findEmptyBucket(key);// 插入数据Buckets[index] = make_pair(key, value);}// 2. 自动扩容void grow() {unsigned NewSize = size() * 2;rehash(NewSize);}
};

6. 使用特点

6.1 线程安全

// 访问 map 时加锁保护
spinlock_t& lock = SideTables()[obj].lock;
lock.lock();
// 操作 map
lock.unlock();

6.2 内存管理

// 定期清理
void cleanup() {// 遍历并清理无效条目for (iterator it = map.begin(); it != map.end();) {if (it->second.expired()) {it = map.erase(it);} else {++it;}}
}

6.3 哈希优化

// 优化的哈希函数
static inline uint32_t ptr_hash(const void *key) {uintptr_t k = (uintptr_t)key;return (uint32_t)(k ^ (k >> 7));
}

主要使用场景总结:

  1. 关联对象存储
  2. 引用计数管理
  3. 弱引用表实现
  4. 方法缓存
  5. 性能优化

使用特点:

  1. 多采用 DenseMap 实现
  2. 注重性能优化
  3. 考虑线程安全
  4. 自动内存管理
  5. 哈希冲突处理

7. 实现差异

7.1 冲突处理

// 开放寻址法
void insert(Key key, Value value) {size_t index = hash(key) & mask;while (table[index] != empty) {index = (index + 1) & mask;  // 线性探测}table[index] = value;
}// 链地址法
void insert(Key key, Value value) {size_t index = hash(key) & mask;table[index].push_back(value);  // 添加到链表
}

7.2 扩容策略

// weak_table_t 的扩容
void grow() {// 当使用率超过 3/4 时扩容if (num_entries >= capacity * 3/4) {resize(capacity * 2);}
}// cache_t 的重建
void rebuild() {// 缓存满时直接清空重建clear();allocate(capacity);
}

7.3 内存管理

// DenseMap 的内存管理
template <typename Key, typename Value>
class DenseMap {// 使用连续内存pair<Key, Value> *Buckets;// 自动扩容void grow() {reallocate(NumEntries * 2);}
};

8. 性能考虑

8.1 查找效率

// 方法缓存优化
IMP cache_t::imp(SEL sel) {// 使用位运算优化mask_t index = (mask_t)(uintptr_t)sel & _mask;return _buckets[index].imp();
}

8.2 空间效率

// weak_table_t 的空间优化
struct weak_entry_t {union {struct {weak_referrer_t *referrers;      // 动态数组};struct {weak_referrer_t  inline_referrers[WEAK_INLINE_COUNT]; // 内联存储};};
};

总结:

  1. 不同场景选择不同的哈希表实现
  2. 需要权衡时间和空间效率
  3. 要考虑线程安全问题
  4. 注意内存管理和性能优化
  5. 合理处理哈希冲突
  6. 选择适当的扩容策略

http://www.ppmy.cn/news/1564704.html

相关文章

【React学习笔记】第三章:React应用

1.使用create-react-app创建 react 应用 1.1 react 脚手架 react提供了一个用于创建 react 项目的脚手架&#xff1a;create-react-app 项目的整体技术架构为&#xff1a;react webpack es6 eslint 1.2 创建项目并启动 打开CMD 第一步&#xff1a; 全局安装react脚手架 …

OpenHarmony-7.IDL工具

IDL 工具 1.openharmony IDL工具 在OpenHarmony中&#xff0c;当应用/系统服务的客户端和服务端进行IPC&#xff08;Inter-Process Communication&#xff09;跨线程通信时&#xff0c;需要定义双方都认可的接口&#xff0c;以保障双方可以成功通信&#xff0c;OpenHarmony ID…

基于PHP的校园新闻发布管理

摘要 近年来&#xff0c;随着互联网技术的迅速发展&#xff0c;人们获取新闻的渠道也变得越来越多样化&#xff0c;已经不再拘束于传统的报纸、期刊、杂志等纸质化的方式&#xff0c;而是通过网络满足了人们获得第一手新闻的愿望&#xff0c;这样更加有助于实现新闻的规范化管…

吴恩达深度学习——神经网络介绍

文章内容来自BV11H4y1F7uH&#xff0c;仅为个人学习所用。 文章目录 什么是神经网络引入神经网络神经元激活函数ReLU隐藏单元 用神经网络进行监督学习监督学习与无监督学习举例 什么是神经网络 引入 已经有六个房子的数据集&#xff0c;横轴为房子大小&#xff0c;纵轴为房子…

【服务器】Ubuntu22.04配置静态ip

Ubuntu2204配置静态ip Ubuntu2204配置静态ip1. 编辑网络配置文件2. 输入下面配置3. 配置生效4. 查看当前ip5. 完成修改 Ubuntu2204配置静态ip 1. 编辑网络配置文件 sudo vim /etc/netplan/00-installer-config.yaml2. 输入下面配置 将静态ip设置为192.168.3.200 &#xff0c;…

PHP企业IM客服系统

&#x1f4ac; 企业IM客服系统——高效沟通&#xff0c;无缝连接的智慧桥梁 &#x1f680; 卓越性能&#xff0c;释放无限可能 在瞬息万变的商业环境中&#xff0c;我们深知沟通的力量。因此&#xff0c;基于先进的ThinkPHP5框架与高性能的Swoole扩展&#xff0c;我们匠心独运…

深度学习项目--基于LSTM的火灾预测研究(pytorch实现)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 LSTM模型一直是一个很经典的模型&#xff0c;这个模型当然也很复杂&#xff0c;一般需要先学习RNN、GRU模型之后再学&#xff0c;GRU、LSTM的模型讲解将…

Java进程内缓存介绍

title: Java 进程内缓存 categories: 编程 Java 中间件 缓存 tags: Java 中间件 缓存 abbrlink: bd2603d3 date: 2022-02-17 22:34:30 permalink: /pages/9632fd/ Java 进程内缓存 关键词&#xff1a;ConcurrentHashMap、LRUHashMap、Guava Cache、Caffeine、Ehcache 一、Concu…