方法是类的一个重要的组成部分,在Objective-C,方法被分为对象方法、类方法。
他们除了-/+不同之外,其他的都相同;他们在内存中是对象方法存储在类对象中,类方法存储在元类中。
那么方法在源码中是什么样子的呢?
#if __has_feature(ptrauth_calls)
#if !__arm64__
#error ptrauth other than arm64e is unimplemented
#endif
// Method lists use process-independent signature for compatibility.
using MethodListIMP = IMP __ptrauth_objc_method_list_imp;
#else
using MethodListIMP = IMP;
#endif
struct method_t {
struct big {
SEL name;
const char *types;
MethodListIMP imp;
};
big &big() const {
ASSERT(!isSmall());
return *(struct big *)this;
}
SEL name() const {
if (isSmall()) {
return (small().inSharedCache()
? (SEL)small().name.get()
: *(SEL *)small().name.get());
} else {
return big().name;
}
}
const char *types() const {
return isSmall() ? small().types.get() : big().types;
}
IMP imp(bool needsLock) const {
if (isSmall()) {
IMP imp = remappedImp(needsLock);
if (!imp)
imp = ptrauth_sign_unauthenticated(small().imp.get(),
ptrauth_key_function_pointer, 0);
return imp;
}
return big().imp;
}
};
在mehtod_t中一个内部struct big 描述了方法在内存中的描述。
#if !__arm64__
#error ptrauth other than arm64e is unimplemented
#endif
// Method lists use process-independent signature for compatibility.
using MethodListIMP = IMP __ptrauth_objc_method_list_imp;
#else
using MethodListIMP = IMP;
#endif
struct big {
SEL name; // 函数名
const char *types; // 编码(返回值类型、参数类型)
MethodListIMP imp; // 指向函数的指针(函数地址)
};
我们可以打印内存中方法,看看他是啥样子的
IMP的实现:
**typedef** **id** **_Nullable** (***IMP**)(**id** **_Nonnull**, **SEL** **_Nonnull**, ...);
代表方法\函数名,一般叫做选择器,底层结构跟char *类似