通过源码分析oc中的类和元类

2020-11-30  本文已影响0人  J扣歪
一 、如何获取 类
+ (Class)class {
    return self;
}

1)通过调用类方法+ (Class)class直接返回self也就是类本身

- (Class)class {
    return object_getClass(self);
}

Class object_getClass(id obj)
{
    if (obj) return obj->getIsa();
    else return Nil;
}

2)通过调用对象的实例方法- (Class)class,然后再通过object_getClass返回这个实例对象的isa所指向的类

Class objc_getClass(const char *aClassName)
{
    if (!aClassName) return Nil;

    // NO unconnected, YES class handler
    return look_up_class(aClassName, NO, YES);
}

3)objc_getClass 通过look_up_class去查找一个以传入的字符命名的类并返回

二 、如何获取 元类

Class objc_getMetaClass(const char *aClassName)
{
    Class cls;

    if (!aClassName) return Nil;

    cls = objc_getClass (aClassName);
    if (!cls)
    {
        _objc_inform ("class `%s' not linked into application", aClassName);
        return Nil;
    }

    return cls->ISA();
}

通过objc_getMetaClass可以获取到一个以传入的字符命名的类的元类,由源码可以看出它是先通过cls = objc_getClass (aClassName);获取到一个类cls,然后忽略获取失败的情况最终通过return cls->ISA();返回了这个类cls的ISA所指向的类。

一 、验证

为了验证上面的描述是否正确

@interface Person : NSObject
@end

@interface Student : NSObject
@end

1)创建两个类Person和Student

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"改变前---%@",objc_getMetaClass("Person"));
    object_setClass([Person class], [Student class]);
    NSLog(@"改变后---%@",objc_getMetaClass("Person"));
}

2)通过object_setClass这句代码可以将一个对象的isa所指向的类赋值成其他的类,现在传入一个类对象Person[Person class],让后将它的isa所指向的类变成Student,最终在控制台比较一下改变前后Person的元类的打印情况。

2020-11-30 16:43:39.038771+0800 Method[3413:231818] 改变前---Person
2020-11-30 16:43:54.842909+0800 Method[3413:231818] 改变后---Student

3)可以看出objc_getMetaClass将Person的元类由Person变成了Student,所以说如果类表示的是一个实例对象的isa所指向的类,那么元类表示的就是一个类对象的isa所指向的类,默认情况下一个类的元类就是它本身。

上一篇 下一篇

猜你喜欢

热点阅读