欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

oc- isa superclass 类 原类

程序员文章站 2022-07-14 15:25:44
...

OC对象 主要分三种:

instance 对象(实例对象)

class 对象(类对象)

meta-class 对象 (元类对象)

1:一个实例对象 在内存中存储的信息:isa指针、其他变量(这个是成员变量的值,比如说,self.age = 10, 10放在里面)

2:类对象

  NSObject *objec1 = [[NSObject alloc] init];
        NSObject *objec2 = [[NSObject alloc] init];
        
        // 获取类对象的三种方式
        Class objectClass1 = [objec1 class];
        Class objectCalss2 = [objec2 class];
        Class objectClass3 = object_getClass(objec1);
        Class objectClass4 = object_getClass(objec2);
        Class objectClass5 = [NSObject class];
        

一个类的类对象是唯一的,在内存中是一份的,所以上述objectClass1、2、3、4、5地址是一样的

2018-07-04 20:39:35.659080+0800 new[4539:831047] 0x7fffb08b9140,0x7fffb08b9140,0x7fffb08b9140,0x7fffb08b9140,0x7fffb08b9140
类对象在内存中存储的信息:isa指针、superclass指针、类的属性信息(@property)、类的对象方法信息(instance method)(减号的方法)、类的协议信息(protocol)、类的成员变量信息(ivar)(这个成员变量是 成员变量的名字、还有成员变量的类型,比方说 string类型,名字叫age)

oc- isa superclass 类 原类

3:meta-class 元类对象

获取元类对象

跟class和实例对象不是一种地址

oc- isa superclass 类 原类


class方法返回的就是类对象,不管你调用多少次,[[NSObject class] class]

元类对象在内存中储存的信息:类方法。

objectMetaClass是NSObject的meta-Class对象

每个类在内存中有且只有一个metal-Class对象

meta-Class对象和class对象的内存结构是一样的,但是用途不一样,在内存中存储的信息主要包括:isa指针、superclass、类方法信息。

可以判断是否是元类对象。:

class_isMetaClass(objectMetaClass);



object_getClass与objc_getClass分别是什么意思


A>: Class objc_getClass(const char *name)

a:传入的是字符串类名,返回对应的类对象。


B>: Class object_getClass(id obj)

a:传进去的obj可能是instance对象、class对象、meta-class对象

b:如果是instance对象,返回class对象

c:如果是class对象,返回的是meta-class对象

d:如果是meta-class对象,返回的是NSObject(基类)的meta-class对象。


C>: -(Class)class 、+(Class)class

返回的就是类对象

oc- isa superclass 类 原类


isa指针:

oc- isa superclass 类 原类

class对象的superclass指针:Student继承自Person,Person继承自NSObject。当Student实例变量去调用实例方法时的过程。

@interface Person : NSObject
{
    int _df;
}

- (void)personMethod;

@end

@implementation Person

- (void)personMethod
{   
}
@end

@interface Student : Person
{
    double _no;
}

- (void)studentMethod;

@end

@implementation Student

- (void)studentMethod
{   
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        Student *stu = [[Student alloc] init];
        [stu personMethod];   
    }
    return NSApplicationMain(argc, argv);
}
这个原理过程就是下面图中所示,stu先按照上图所示的,stu的实例对象的isa指针,找到本身stu类(因为类里有对象方法,同时有superclass指针,)发现并未有该方法,根据superclass指针,找到Person的类对象,就能够找到Person类的对象方法,正好有刚调用的personMehod方法,即可实现。

oc- isa superclass 类 原类

假设Student类对象调用 load方法,那么过程就是下面图中所示:Student类根据isa指针找到自己的meta-class对象,在元类对象中并未发现load方法,就会根据superclass找到父类的meta-class对象,也就是Person的元类对象,发现也没有,再根据person原类对象的superclass找到父类也就是NSObject的meta-class对象,从而找到load方法。这里需要注意,假设NSObject没有load方法,那么现在NSObject这个基类的meta-class的superclass会找到NSObject的class,如果再没找到,才会报错。

oc- isa superclass 类 原类

总结一下:就是superclass找的是类方法 都是找的meta-class对象  如果找的是实例方法 ,那么找的都是类对象。

每一个类 都有自己的元类对象

oc- isa superclass 类 原类

oc- isa superclass 类 原类

假设Person和Student都有实例test方法。【student test】调用的时候,会直接调用student的test方法。原因:面向对象的思想的话是子类重写父类,那么肯定会调用子类的方法。如果按照上面的本质去解释的话:子类isa指针找到本类class对象,发现有test方法,那么它就直接执行了,不会再找父类了。


如果是


验证问题:

这个是NSObject分类,只实现了实例方法test。
#import "NSObject+test.h"

@implementation NSObject (test)

- (void)test
{
    NSLog(@"sfd");
}



@end
这里是person方法,并未实现test类方法
@interface Person : NSObject

+ (void)test;

@end

@implementation Person

@end

#import "NSObject+test.h"
int main(int argc, const char * argv[]) { @autoreleasepool { 
[Person test];
 }
 return NSApplicationMain(argc, argv);
}


那么这个能够调用? 是否会报错? 答案很明显,不会

2018-07-10 20:08:51.314998+0800 new[1765:218776] sfd
原因就是上面基类的meta-class方法如果没有找到对应的类方法的时候,它的superclass指针会指向基类的class对象,也就是NSObject类,找到了test方法,所以就调用了。对于本质objc_Send()方法而言,是没有减号和加号的区别方法的,所以直接调用。

注意:

isa不是直接指向本类的对象的,从64bit开始,需要一次运算才能计算出真实的地址

oc- isa superclass 类 原类

oc- isa superclass 类 原类

oc- isa superclass 类 原类

但是superclass是直接指向的,并不需要转换

oc- isa superclass 类 原类


2:对象的isa指针指向哪里?

instance对象isa指向class对象

class对象isa指向meta-class对象

meta-class对象isa指向基类meta-class对象


3:OC的类信息存放在哪里?

对象方法、属性、成员变量、协议信息存放在class对象中

类方法存在meta-class对象中

成员变量的具体值,存放在instance对象







相关标签: 分类