上课知识回顾:
证明:对象方法存在类里面,类方法存在元类里面!!!!!
源码分析:
class_getInstanceMethod:获取类的对象方法!!
Method class_getInstanceMethod(Class cls, SEL sel)
{
if (!cls || !sel) return nil;
// This deliberately avoids +initialize because it historically did so.
// This implementation is a bit weird because it's the only place that
// wants a Method instead of an IMP.
#warning fixme build and search caches
// Search method lists, try method resolver, etc.
lookUpImpOrForward(nil, sel, cls, LOOKUP_RESOLVER);
#warning fixme build and search caches
return _class_getMethod(cls, sel);
}
static Method _class_getMethod(Class cls, SEL sel)
{
mutex_locker_t lock(runtimeLock);
return getMethod_nolock(cls, sel);
}
getMethod_nolock(Class cls, SEL sel)
{
method_t *m = nil;
runtimeLock.assertLocked();
// fixme nil cls?
// fixme nil sel?
ASSERT(cls->isRealized());
while (cls && ((m = getMethodNoSuper_nolock(cls, sel))) == nil) {
cls = cls->superclass;
}
return m;
}
getMethodNoSuper_nolock(Class cls, SEL sel)
{
runtimeLock.assertLocked();
ASSERT(cls->isRealized());
// fixme nil cls?
// fixme nil sel?
auto const methods = cls->data()->methods();
for (auto mlists = methods.beginLists(),
end = methods.endLists();
mlists != end;
++mlists)
{
// <rdar://problem/46904873> getMethodNoSuper_nolock is the hottest
// caller of search_method_list, inlining it turns
// getMethodNoSuper_nolock into a frame-less function and eliminates
// any store from this codepath.
method_t *m = search_method_list_inline(*mlists, sel);
if (m) return m;
}
return nil;
}
核心代码:auto const methods = cls->data()->methods();
** 是不是验证了我们上节课对应的,取类的对象方法,即在data()->methods()中取,有的话返回地址,没有的话返回0
源码分析:
class_getClassMethod:获取类的类方法(等价于 获取该类 元类 的实例化方法)
Method class_getClassMethod(Class cls, SEL sel)
{
if (!cls || !sel) return nil;
return class_getInstanceMethod(cls->getMeta(), sel);
}
Class getMeta() {
if (isMetaClass()) return (Class)this;
else return this->ISA();
}
总结: 获取一个类的类方法 其实等价于,获取该元类的实例化方法 (如果是元类的话,则不需要取该元类的元类了,直接返回,不继续递归了,不然的话会无限递归循环)
结合上小节的实例lldb
来分析:
@interface LGPerson : NSObject
{
NSString* interst;
}
@property (nonatomic, copy) NSString *nickName;
@property (nonatomic, strong) NSString *name;
//对象方法
- (void)test_InstanceMethod;
//类方法
+ (void)test_ClassMethod;
@end
论证:
1. Method method1 = class_getInstanceMethod([LGPerson Class], @selector(test_InstanceMethod));//有
1 :LGPerson类拥有"test_InstanceMethod"的对象方法,所以此处 可以 得到结果
Class metaClass = objc_getMetaClass("LGPerson");//获取元类
Method method2 = class_getInstanceMethod(metaClass, @selector(test_InstanceMethod));//无
2 :LGPerson类的 元类 没有"test_InstanceMethod"的对象方法,拥有类方法"test_ClassMethod"的方法,所以此处 不可以 得到结果
Method method3 = class_getInstanceMethod([LGPerson Class], @selector(test_ClassMethod));//无
3 :LGPerson类,没有类方法"test_ClassMethod"的方法,所以此处 不可以 得到结果
Class metaClass = objc_getMetaClass("LGPerson");//获取元类
Method method4 = class_getInstanceMethod(metaClass, @selector(test_ClassMethod));//有
4 :LGPerson类的 元类 ,拥有类方法"test_ClassMethod"的方法,所以此处 可以 得到结果
const char *className = class_getName([LGPerson Class]);
Class metaClass = objc_getMetaClass(className);
//得不到结果!
Method method1 = class_getClassMethod(pClass, @selector(test_InstanceMethod));//无
//得不到结果!
Method method2 = class_getClassMethod(metaClass, @selector(test_InstanceMethod));//无
//可以得到结果~
Method method3 = class_getClassMethod(pClass, @selector(test_ClassMethod));//有
//可以得到结果~(元类的话,则不需要取该元类的元类了,直接返回,不继续递归了,不然的话会无限递归循环)
Method method4 = class_getClassMethod(metaClass, @selector(test_ClassMethod));//有
源码分析:
[Class isKindOfClass]: 类方法
+ (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = self->ISA(); tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
初始赋值为该类的 “元类”,循环从该元类的父类找,直到找到该元类及其父类与参数cls等同的情况,才返回 “true”,否则返回“false”
源码分析:
[Class isMemberOfClass]:类方法
+ (BOOL)isMemberOfClass:(Class)cls {
return self->ISA() == cls;
}
初始赋值为该类的 “元类”,判断该元类是否与参数“cls”等同,相同返回 “true”,否则返回“false”
源码分析:
[objc isKindOfClass]:对象方法
- (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
初始赋值为该“类“,循环从该类的父类找,直到找到该类及其父类与参数cls等同的情况,才返回 “true”,否则返回“false”
源码分析:
[objc isKindOfClass]:对象方法
- (BOOL)isMemberOfClass:(Class)cls {
return [self class] == cls;
}
初始赋值为该“类“,判断该类是否与参数cls等同,等同返回 “true”,否则返回“false”
实战:
BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
1:此处调用"类方法",NSObject的"元类"不同于NSObject,跑循环之后可以找到与NSObject相同的类 ,所以此处为 ”true“
BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
2:此处调用"类方法",NSObject的"元类"不等同于NSObject,所以此处为 ”false“
BOOL re3 = [(id)[LGPerson class] isKindOfClass:[LGPerson class]];
3:此处调用"类方法",LGPerson的"元类"不等同于LGPerson,即使循环查找父类,也不存在等同的情况,所以此处为 ”false“
BOOL re4 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]];
4:此处调用"类方法",LGPerson的"元类"不等同于LGPerson,所以此处为 ”false“
const char *className = class_getName(LGPerson.class);
Class metaClass = objc_getMetaClass(className);
BOOL re5 = [(id)[LGPerson class] isMemberOfClass:metaClass];
5:此处调用"类方法",LGPerson的"元类"不等同于LGPerson的元类,所以此处为 ”ture"
BOOL re6 = [(id)[LGPerson class] isKindOfClass:[NSObject class]];
6:此处调用"类方法",LGPerson的"元类"虽然不等同于NSObject类,但是跑父类的循环,会找到与NSObject相同的类,所以此处为 ”ture"
BOOL re7 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];
BOOL re8 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];
BOOL re9 = [(id)[LGPerson alloc] isKindOfClass:[LGPerson class]];
BOOL re10 = [(id)[LGPerson alloc] isMemberOfClass:[LGPerson class]];
7:true 8:true 9: true 10:true 不多说什么
**记住:只要isMemberOfClass成立,则isKindOfClass 一定成立
网友评论