OC中对象方法调用时,会转化为Objc_msgSend(self, SEL, ...)函数,然后通过SEL
在类对象中查找方法进行调用,但是这个SEL究竟是什么呢?
源码
一、SEL是什么
首先通过源码来查看,我是通过搜索selector查看到了这句代码("selector '%s'", sel_getName(sel));
const char *sel_getName(SEL sel)
{
if (!sel) return "<null selector>";
return (const char *)(const void*)sel;
}
由上可知,SEL sel
本质可以强转为const char *
, 也就是说是字符串.
再运行代码可得:
NSLOG(@"testMotionEffect = %s", @selector(testMotionEffect));
// 结果是
2020-08-19 15:37:16.437488+0800 首页滑动DEMO[1960:104060] testMotionEffect = testMotionEffect
所以SEL
也就是方法名本身字符串.
二、方法列表是怎么存储对象方法的?
通过查看的上面的那句代码位置上方找到这句代码cache_t *cache = &isa->cache;
查看cache_t如下:
struct cache_t {
struct bucket_t *_buckets;
mask_t _mask;
mask_t _occupied;
里面的_buckets
装着一个元素为bucket_t
数组
struct bucket_t {
private:
cache_key_t _key;
IMP _imp;
};
IMP是方法的实现地址,所以由此可以推断,系统存储缓存调用方法的方式是isa->cache;
, 这个cache
里面是由一个数组来存放的,存放的元素是一个一个的bucket_t
, 且key=@selector(method), _imp=方法实现的地址。
网友评论