美文网首页iOS笔记
浅谈iOS isa指针

浅谈iOS isa指针

作者: 不会武功的陈真 | 来源:发表于2019-11-20 16:19 被阅读0次

为什么突然想写一篇关于isa的文章呢!是在写kvo原理的时候谈到了isa。有些同学就问我isa到底是什么。咱们就简单的看看

要讲isa 就要了解 instance(实例) class object(类对象) metaclass(元类)

instance(实例)

在我们开发的时候,总有时会用id来接收一些对象。但是大家想过id是怎么实现的吗?看下面这段代码,这是objc/objc.h里面摘出来的代码。
不难看出,id是一个objc_object类型的结构体指针,这个结构体里面只有一个 Class类型的变量isa(还有这个对象自己定义的相关属性等,这里就不讨论)。我们创建对象的时候,其实内部是创建了一个这样的结构体。

/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;

/// Represents an instance of a class.
struct objc_object {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};

/// A pointer to an instance of a class.
typedef struct objc_object *id;

说道这里咱们明白了实例的本质,是一个结构体,里面包含了一个 Class类型的变量isa

class object(类对象) metaclass(元类)

什么是类对象,它也是这个类生成的一个对象(但是明显不是该类的实例,下面我会有验证),但是这个对象里面包含的东西更多,类对象是一个objc_class结构体,下面我看看这个结构体的成员

struct objc_class {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class _Nullable super_class                              OBJC2_UNAVAILABLE;
    const char * _Nonnull name                               OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list * _Nullable ivars                  OBJC2_UNAVAILABLE;
    struct objc_method_list * _Nullable * _Nullable methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE;
    struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */

这个结构体里面也包含Class类型 isa ,还有Class类型的 superClass,咱们这边只研究的这两个,其他的咱们暂时先不管

类对象怎么获取?最简单的方法[ClassName class],下面我们探究一下isa 和类对象关系
先给大家介绍两个方法
object_getClass用于获取对象的isa指针指向的对象
class_isMetaClass用于判断Class对象是否为元类
下面是代码

#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface Person: NSObject


@property(nonatomic,strong) NSString *tiantian;
@end

@implementation Person

+(void)tt{
    NSLog(@"tt");
}


@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        Person *p = [[Person alloc] init];
        Person *p1 = [[Person alloc] init];
//---------------------------------------------------------------------------------
        //实例对象调用class方法 获取类对象
        NSLog(@"[p class] - %@",[p class]);
        //实例对象调用class方法 获取类对象
        NSLog(@"[p1 class] - %@",[p1 class]);
        //类名调用class方法 获取类对象
        NSLog(@"[Person class] - %@\n",[Person class]);
//---------------------------------------------------------------------------------
        //获取p的isa
        NSLog(@"object_getClass(p) - %@",object_getClass(p));
        //获取p1的isa
        NSLog(@"object_getClass(p1) - %@",object_getClass(p1));
        //获取类对象的isa
        NSLog(@"object_getClass([p class]) - %@",object_getClass([p class]));
        
 
//---------------------------------------------------------------------------------
    }
    return 0;
}

MyTextKVCKVO[5141:12156410] [p class] - Person
MyTextKVCKVO[5141:12156410] [p1 class] - Person
MyTextKVCKVO[5141:12156410] [Person class] - Person
MyTextKVCKVO[5141:12156410] object_getClass(p) - Person
MyTextKVCKVO[5141:12156410] object_getClass(p1) - Person
MyTextKVCKVO[5141:12156410] object_getClass([p class]) - Person

运行完了之后看结果 一脸懵逼。怎么都一样?????
我们就仔细的判断一下 具体是什么情况,再看下面的代码

#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface Person: NSObject


@property(nonatomic,strong) NSString *tiantian;
@end

@implementation Person

+(void)tt{
    NSLog(@"tt");
}


@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        Person *p = [[Person alloc] init];
        Person *p1 = [[Person alloc] init];

        //输出 1 。 结论:不同对象的 类对象 是一样的
        NSLog(@"%d",[p class] == [p1 class]);
        //输出 1 , 实例对象获取的类对象 和 类名获取的类对象是一样的
        NSLog(@"%d",[p class] == [Person class]);
//---------------------------------------------------------------------------------
        //类对象 和 这个 p的isa是否相等
        NSLog(@"%d",[p class] == object_getClass(p));
        //类对象 和 这个 p1的isa是否相等
        NSLog(@"%d",[p class] == object_getClass(p1));
 
    }
    return 0;
}

MyTextKVCKVO[5228:12166573] 1
MyTextKVCKVO[5228:12166573] 1
MyTextKVCKVO[5228:12166573] 1
MyTextKVCKVO[5228:12166573] 1

根据上见面的结果咱们可以得出两个结论:
1、一个类的类对象(不管是对象获取,还是类名获取)都是同一个[Person class]
2、我们可以猜测一个类的所有实例对象的isa都是指向同一个 类对象[Person class]

在看superClass

#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface Person: NSObject


@property(nonatomic,strong) NSString *tiantian;
@end

@implementation Person

+(void)tt{
    NSLog(@"tt");
}


@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        Person *p = [[Person alloc] init];

        //获取p的isa
        Class p_isa = object_getClass(p);
        NSLog(@"%@",p_isa);
        
        //获取类对象的superClass
        Class p_isa_superClass = class_getSuperclass(p_isa);
        NSLog(@"%@",p_isa_superClass);
        
        //获取p对象的isa 的 isa
        Class p_isa_isa = object_getClass(p_isa);
        NSLog(@"%@",p_isa_isa);
        
        //判断p的isa 和 (p对象的isa的isa)是否一样
        NSLog(@"%d",p_isa == p_isa_isa);
        
        //判断p_isa 是不是元类
        NSLog(@"%d",class_isMetaClass(p_isa));
        //判断p_isa_isa 是不是元类
        NSLog(@"%d",class_isMetaClass(p_isa_isa));
        
    }
    return 0;
}

MyTextKVCKVO[5433:12185744] Person
MyTextKVCKVO[5433:12185744] NSObject
MyTextKVCKVO[5433:12185744] Person
MyTextKVCKVO[5433:12185744] 0
MyTextKVCKVO[5433:12185744] 0
MyTextKVCKVO[5433:12185744] 1

总结:一个实例对象isa指向的是这个对象的类对象类对象isa指向的是 该类的元类
下面的图可以加强理解

910291-57780799dbe7fd12.png

咱们再想一下 superClass 也是Class对象,也会有isa 和superClass。所以就能一直找到顶层父类,下面是一个大神做的图,总结的很好,也容易懂。


851897-847ffb4b1d53ef23.png

相关文章

  • 浅谈iOS isa指针

    为什么突然想写一篇关于isa的文章呢!是在写kvo原理的时候谈到了isa。有些同学就问我isa到底是什么。咱们就简...

  • 4-1 内存管理

    1.内存布局 2.iOS内存管理方案 [isa指针保存了内存管理的信息] 2.iOS内存管理方案 [isa指针...

  • iOS isa指针

    isa 指针,表示这个对象是一个什么类。而 Class 类型, 也就是 struct objc_class * ,...

  • iOS isa指针

    在Objective-C中,任何类的定义都是对象。类和类的实例没有任何本质上的区别。任何对象都有isa指针。 is...

  • iOS - isa指针

    [toc] 参考 isa指针 isa 简介 isa (is a kind of) 是一个 Class 类型的指针,...

  • iOS ISA指针

    https://opensource.apple.com/tarballs/objc4/[https://open...

  • iOS:isa指针

    一、联合体 1. 概念 联合体,是一种特殊的数据类型,其目的是节省内存。联合体内部可以定义多种数据类型,但是同一时...

  • iOS面试题:objc中向一个nil对象发送消息将会发生什么?

    原文:iOS面试题大全 首先,需要搞明白2个问题: 什么是isa指针 消息传递机制 isa指针是用于对象指向类对象...

  • runtime面试复习

    runtime isa指针的含义 分为指针型isa:isa的値代表Class的地址,非指针型isa :isa的値的...

  • 1.8、iOS面试题之语法

    1、isa指针?(对象的isa,类对象的isa,元类的isa都要说) 对象的isa指针指向所属的类 类的isa指针...

网友评论

    本文标题:浅谈iOS isa指针

    本文链接:https://www.haomeiwen.com/subject/jnuxuctx.html