本系列博客是本人的源码阅读笔记,如果有 iOS 开发者在看 runtime 的,欢迎大家多多交流。为了方便讨论,本人新建了一个微信群(iOS技术讨论群),想要加入的,请添加本人微信:zhujinhui207407,【加我前请备注:ios 】,本人博客http://www.kyson.cn 也在不停的更新中,欢迎一起讨论
本文完整版详见笔者小专栏:https://xiaozhuanlan.com/runtime
背景
今天我们开始讲解 runtime 中一个非常重要的数据结构: maptable,它是 runtime 中存储各类数据的重要的类,这些数据包含但不限于 runtime 中所有的类,所有的协议等。为了方便大家阅读 maptable 的源码,笔者将这个文件剥离出原项目,并放到 GitHub 中供大家研究:
https://github.com/zjh171/RuntimeSample
全局搜索maptable看到70多个结果
除掉maptable
也有20多个引用。可见了解maptable
对runtime
有比较重要的作用。为了方便后面笔者对代码分析,这里对maptable.h
以及maptable.mm
做个介绍。
进入maptable.h
发现NXMapTable的定义如下:
typedef struct _NXMapTable {
/* private data structure; may change */
const struct _NXMapTablePrototype *prototype;
unsigned count;
unsigned nbBucketsMinusOne;
void *buckets;
} NXMapTable
其中_NXMapTablePrototype
的定义如下:
typedef struct _NXMapTablePrototype {
unsigned (*hash)(NXMapTable *, const void *key);
int (*isEqual)(NXMapTable *, const void *key1, const void *key2);
void (*free)(NXMapTable *, void *key, void *value);
int style; /* reserved for future expansion; currently 0 */
} NXMapTablePrototype
除了NXMapTable
以及NXMapTablePrototype
外还有一个结构体NXMapState
:
typedef struct {int index;} NXMapState;
该文件的文件头的注释如下:
This module allows hashing of arbitrary associations [key -> value]. Keys and values must be pointers or integers, and client is responsible for allocating/deallocating this data. A deallocation call-back is provided.
意思是,该模块通过键值对提供了对象之间的散列关系,其中,键和值必须是指针或者是整数。用户需要负责对象的创建以及释放,该对象提供了释放的回调函数而这三个结构体应该就是这个对象的实体相关的信息。
分析
在讲解这三个结构体之前,笔者先讲一些C的基础知识。我们注意到文件maptable.h
中大部分方法前都加了OBJC_EXPORT
修饰符,方法后也加了修饰符。为了理解修饰符的作用,我们可以先全局搜索一下相关的修饰符。
OBJC_EXPORT
继续往下查看发现后面的方法都是以OBJC_EXPORT
开头,以OBJC_MAP_AVAILABILITY
结尾,那么这两个宏的作用是什么呢?笔者全局搜索了一下,看到了其定义:
#if !defined(OBJC_EXPORT)
# define OBJC_EXPORT OBJC_EXTERN OBJC_VISIBLE
#endif
OBJC_EXPORT
应该未被定义是显而易见的,因为如果被定义的话,
# define OBJC_EXPORT OBJC_EXTERN OBJC_VISIBLE
就不被执行,肯定会报错。因此我们只需要分析OBJC_EXTERN
和OBJC_VISIBLE
宏定义,笔者继续分析这两个宏。接下来一一分析:
本文详细版请见:
iOS开发之runtime(23):maptable介绍(一)
广告
我的首款个人开发的APP壁纸宝贝上线了,欢迎大家下载。