ococ

OC中方法@selector()的本质是什么?

2020-08-19  本文已影响0人  Sweet丶

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=方法实现的地址。

上一篇 下一篇

猜你喜欢

热点阅读