首先大家要知道的是 万物皆对象 类实例化出的对象叫实例对象 类也可以称为类对象 都是对象,那么这样我们就可以探索下底层 对象到底是什么
分析源码
我们可以将.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.
翻译过来就是一个指向当前实例对象所属的类的指针
因为isa
是Class 类型
全局搜 得到
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 与类的关系
如果理解有问题欢迎大家提出意见和建议
喜欢点个赞👍🏻 👍🏻 👍🏻