美文网首页
OC 对象的本质

OC 对象的本质

作者: 水蜜桃看看就好 | 来源:发表于2021-05-14 14:47 被阅读0次

首先大家要知道的是 万物皆对象 类实例化出的对象叫实例对象 类也可以称为类对象 都是对象,那么这样我们就可以探索下底层 对象到底是什么

分析源码

我们可以将.m文件转换成.cpp 文件 通过以下代码来将代码进行转换

clang -rewrite-objc main.m -o main.cpp

main.m 代码如下

#import <Foundation/Foundation.h>


@interface LGPerson: NSObject
@property(nonatomic,copy)NSString *name;
@end
@implementation LGPerson
@end

int main(int argc, const char * argv[]) {
   
    LGPerson *person = [[LGPerson alloc]init];
    person.name = @"shadiao";
    NSLog(@"%@", person.name);
    return 0;
}

转换成后main.cpp 得到关键代码展示 直接在文件中搜你定义的类名LGPerson

extern "C" unsigned long OBJC_IVAR_$_LGPerson$_name;
struct LGPerson_IMPL {
    struct NSObject_IMPL NSObject_IVARS;
    NSString *_name;
};

// @property(nonatomic,copy)NSString *name;
/* @end */

// @implementation LGPerson

static NSString * _I_LGPerson_name(LGPerson * self, SEL _cmd) { return (*(NSString **)((char *)self + OBJC_IVAR_$_LGPerson$_name)); }
extern "C" __declspec(dllimport) void objc_setProperty (id, SEL, long, id, bool, bool);

static void _I_LGPerson_setName_(LGPerson * self, SEL _cmd, NSString *name) { objc_setProperty (self, _cmd, __OFFSETOFIVAR__(struct LGPerson, _name), (id)name, 0, 1); }
// @end

int main(int argc, const char * argv[]) {

    LGPerson *person = ((LGPerson *(*)(id, SEL))(void *)objc_msgSend)((id)((LGPerson *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("LGPerson"), sel_registerName("alloc")), sel_registerName("init"));
    ((void (*)(id, SEL, NSString *))(void *)objc_msgSend)((id)person, sel_registerName("setName:"), (NSString *)&__NSConstantStringImpl__var_folders_g6__hcbx3jn56v_lhk2gxkhxn900000gn_T_main_70bb97_mi_0);
    NSLog(((NSString *(*)(id, SEL))(void *)objc_msgSend)((id)person, sel_registerName("name")));
    return 0;
}

通过.cpp文件可以看出 LGPerson类的定义在底层其实是一个结构体,且结构体中包含 一个结构体成员变量struct NSObject_IMPL NSObject_IVARS; 和自己定义的name属性

分析下struct NSObject_IMPL NSObject_IVARS; 这是什么,通过全局代码搜索

struct NSObject_IMPL {
    Class isa;
};

是一个NSObject结构体对象 且里面包含一个Class isa 这样就不难看出 我们定义的LGPerson 也包含一个 isa 那么问题来了 这个isa 是什么? 有什么用?

isa是什么?

其实我们通过查看文档,苹果官方是这么说的
A pointer to the class definition of which this object is an instance.翻译过来就是一个指向当前实例对象所属的类的指针
因为isaClass 类型 全局搜 得到

typedef struct objc_class *Class;

是一个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 可以这么理解 isa是什么

总结:isa是一个 objec_class的结构体指针 objc_class 是一个对象类 那么就大致理解了文档所说的 isa 其实就是一个指向当前实例对象所属类的指针

isa的作用可以理解为 可以通过分析isa 拿到当前对象所属类的一些信息

后面我会总结isa 与类的关系

如果理解有问题欢迎大家提出意见和建议
喜欢点个赞👍🏻 👍🏻 👍🏻

相关文章

网友评论

      本文标题:OC 对象的本质

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