OC对象的分类

2020-09-26  本文已影响0人  凌云01

对象的isa指向哪里?
类信息存放在哪里?

Objective-C对象,简称OC对象,分为三类:

instance对象就是通过类alloc出来的对象,每次alloc都会产生新的instance对象,占据不同的内存

instance对象在内存中存储的信息有哪些?

每个类在内存中有且只有一份对象。
class对象在内存中存储的信息有哪些?

每个类在内存中有且只有一份meta-class对象。
meta-class对象和class对象的内存结构中是一样的只是用途不一样,在内存中存储的信息包括:

调用对象方法和类方法的过程

对象方法调用过程

类方法调用过程

superclass的调用过程


@interface Person : NSObject<NSCopying>

@interface Student : Person

当Student的instance对象要调用Person中的对象方法时,会先通过isa指针找到Student的class,然后通过superclass找到Person的class,最后找到对象方法的实现进行调用。

当Student的class要调用Person中的类方法时,会先通过isa指针找到Student的meta-class,然后通过superclass找到Person的meta-class,最后找到类方法的实现进行调用。

image.png

看两个函数

OBJC_EXPORT BOOL class_isMetaClass(Class cls) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);

OBJC_EXPORT Class object_getClass(id obj) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);

class_isMetaClass用于判断Class对象是否为元类,object_getClass用于获取对象的isa指针指向的对象。

再看如下代码:

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *p = [[Person alloc] init];
        //输出1
        NSLog(@"%d", [p class] == object_getClass(p));
        //输出0
        NSLog(@"%d", class_isMetaClass(object_getClass(p)));
        //输出1
        NSLog(@"%d", class_isMetaClass(object_getClass([Person class])));
        //输出0
        NSLog(@"%d", object_getClass(p) == object_getClass([Person class]));
    }
    return 0;
}

通过代码可以看出,一个实例对象通过class方法获取的Class就是它的isa指针指向的类对象,而类对象不是元类,类对象的isa指针指向的对象是元类。

思考题

@interface Person : NSObject<NSCopying>
+ (void)test;
@end
@implementation Person
@end

@interface NSObject (Test)
+ (void)test;
@end
@implementation NSObject (Test)
-(void)test{
    NSLog(@"NSObject+Test");
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        [Person test];
        [NSObject test];
    }
    return 0;
}

以上代码能运行成功吗?

答案:能运行成功,从isa,superclass去考虑(通过objc_msgSend查找方法时,不知道是实例方法还是类方法)

上一篇 下一篇

猜你喜欢

热点阅读