iOS 1.NSObject--- clang编译OC成C+
2019-10-27 本文已影响0人
龙之天下
1.声明一个类:BaseObj
BaseObj.h
@interface BaseObj : NSObject
@end
BaseObj.m
NS_ASSUME_NONNULL_END
@implementation BaseObj
@end
2.clang编译OC成C++或者C文件
$:cd --BaseObj的文件路径
$: clang -rewrite-objc BaseObj.m
3.OC--->C++或者C的源码
#pragma clang assume_nonnull begin
#ifndef _REWRITER_typedef_BaseObj
#define _REWRITER_typedef_BaseObj
typedef struct objc_object BaseObj;
typedef struct {} _objc_exc_BaseObj;
#endif
struct BaseObj_IMPL {
struct NSObject_IMPL NSObject_IVARS;
// 如果有属性 : 1.编译期间生成成员变量
// NSString * _Nonnull _name;
};
/* @end */
#pragma clang assume_nonnull end
// @implementation BaseObj
// @end
/*
* 存放property的结构体
* 具体存储的数据为_prop_list_t
原型:@property (copy,nonatomic)NSString *name;
实际内容:{{"name","T@\"NSString\",C,N,V_name"}}
**/
struct _prop_t {
const char *name;
const char *attributes;
};
struct _protocol_t;
/*
*类中方法的结构体,cmd和imp的关系是一一对应的关系
*创建对象生成isa指针,指向这个对象的结构体时
*同时生成了一个表"Dispatch table"通过这个 _cmd的编号找到对应方法
*使用场景:
*例如方法交换,方法判断。。。
**/
struct _objc_method {
struct objc_selector * _cmd; //SEL 对应着OC中的@selector()
const char *method_type; //方法的类型
void *_imp; //方法的地址
};
/*
* 表示这个类中所遵守的协议对象
* 使用场景:
* 判断类是否遵守这个协议,从而动态添加、重写、交换某些方法,来达到某些目的
*
**/
struct _protocol_t {
void * isa; // NULL
const char *protocol_name;
const struct _protocol_list_t * protocol_list; // super protocols
const struct method_list_t *instance_methods;// 实例方法
const struct method_list_t *class_methods;//类方法
const struct method_list_t *optionalInstanceMethods;//可选的实例方法
const struct method_list_t *optionalClassMethods;//可选的类方法
const struct _prop_list_t * properties; //属性列表
const unsigned int size; // sizeof(struct _protocol_t)
const unsigned int flags; // = 0
const char ** extendedMethodTypes;//扩展的方法类型
};
/*
* 类的成员变量的结构体
* 原型: NSString *name;
* 存储内容:
*{(unsigned long int *)&OBJC_IVAR_$_SLObject_var$_name, "_name", "@\"NSString\"", 3, 8}
**/
struct _ivar_t {
unsigned long int *offset; // pointer to ivar offset location
const char *name; //名字
const char *type;
unsigned int alignment;
unsigned int size; //大小
};
/*
* 这个就是类中的各种方法、属性、等等信息
* 底层也是一个结构体
* 名称、方法列表、协议列表、变量列表、layout、properties。。
**/
struct _class_ro_t {
unsigned int flags; //1
unsigned int instanceStart; //sizeof(struct _class_t), sizeof(struct _class_t)
unsigned int instanceSize; //
unsigned int reserved; //
const unsigned char *ivarLayout; //
const char *name; //"SLGame"
const struct _method_list_t *baseMethods;//方法列表
const struct _objc_protocol_list *baseProtocols;//协议列表
const struct _ivar_list_t *ivars;//成员变量列表
const unsigned char *weakIvarLayout;//弱引用布局。
const struct _prop_list_t *properties;//属性列表。
};
/*
* 类本身
* oc在创建类的时候都会创建一个 _class_t的结构体
* 我的理解是在runtime中的object-class结构体在底层就会变成_class_t结构体
*/
struct _class_t {
struct _class_t *isa; //元类的指针
struct _class_t *superclass;//父类的指针
void *cache; //缓存
void *vtable;
struct _class_ro_t *ro; //这个就是类中的各种方法、属性、等等信息
};
/*
* 类扩展的结构体
* 在OC中写的分类
**/
struct _category_t {
const char *name; //名称
struct _class_t *cls; //这个是哪个类的扩展
const struct _method_list_t *instance_methods;//实例方法列表
const struct _method_list_t *class_methods;//类方法列表
const struct _protocol_list_t *protocols;//协议列表
const struct _prop_list_t *properties;//属性列表
};
extern "C" __declspec(dllimport) struct objc_cache _objc_empty_cache;
#pragma warning(disable:4273)
2.实例
static struct _class_ro_t _OBJC_METACLASS_RO_$_BaseObj __attribute__ ((used, section ("__DATA,__objc_const"))) = {
1, sizeof(struct _class_t), sizeof(struct _class_t),
(unsigned int)0,
0,
"BaseObj",
0,
0,
0,
0,
0,
};
static struct _class_ro_t _OBJC_CLASS_RO_$_BaseObj __attribute__ ((used, section ("__DATA,__objc_const"))) = {
0, sizeof(struct BaseObj_IMPL), sizeof(struct BaseObj_IMPL),
(unsigned int)0,
0,
"BaseObj",
0,
0,
0,
0,
0,
};
extern "C" __declspec(dllimport) struct _class_t OBJC_METACLASS_$_NSObject;
extern "C" __declspec(dllexport) struct _class_t OBJC_METACLASS_$_BaseObj __attribute__ ((used, section ("__DATA,__objc_data"))) = {
0, // &OBJC_METACLASS_$_NSObject,
0, // &OBJC_METACLASS_$_NSObject,
0, // (void *)&_objc_empty_cache,
0, // unused, was (void *)&_objc_empty_vtable,
&_OBJC_METACLASS_RO_$_BaseObj,
};
extern "C" __declspec(dllimport) struct _class_t OBJC_CLASS_$_NSObject;
extern "C" __declspec(dllexport) struct _class_t OBJC_CLASS_$_BaseObj __attribute__ ((used, section ("__DATA,__objc_data"))) = {
0, // &OBJC_METACLASS_$_BaseObj,
0, // &OBJC_CLASS_$_NSObject,
0, // (void *)&_objc_empty_cache,
0, // unused, was (void *)&_objc_empty_vtable,
&_OBJC_CLASS_RO_$_BaseObj,
};
static void OBJC_CLASS_SETUP_$_BaseObj(void ) {
OBJC_METACLASS_$_BaseObj.isa = &OBJC_METACLASS_$_NSObject;
OBJC_METACLASS_$_BaseObj.superclass = &OBJC_METACLASS_$_NSObject;
OBJC_METACLASS_$_BaseObj.cache = &_objc_empty_cache;
OBJC_CLASS_$_BaseObj.isa = &OBJC_METACLASS_$_BaseObj;
OBJC_CLASS_$_BaseObj.superclass = &OBJC_CLASS_$_NSObject;
OBJC_CLASS_$_BaseObj.cache = &_objc_empty_cache;
}
#pragma section(".objc_inithooks$B", long, read, write)
__declspec(allocate(".objc_inithooks$B")) static void *OBJC_CLASS_SETUP[] = {
(void *)&OBJC_CLASS_SETUP_$_BaseObj,
};
static struct _class_t *L_OBJC_LABEL_CLASS_$ [1] __attribute__((used, section ("__DATA, __objc_classlist,regular,no_dead_strip")))= {
&OBJC_CLASS_$_BaseObj,
};
static struct IMAGE_INFO { unsigned version; unsigned flag; } _OBJC_IMAGE_INFO = { 0, 2 };
简单总结:编译--->运行时
.h文件
1.编译期间生成成员变量比如:_name(@property (nonatomic,copy) NSString *name;)
.m
1)、自动生成成员变量 2)、setter 3)、get
2.自动生成property的结构体(name名字 attributes)
3._objc_method 类对象的(SEL 对应着OC中的@selector(),类型和地址)方法的结构体
4._protocol_t的结构体(isa,protocol_name,super protocols,instance_methods,class_methods,optionalInstanceMethods,optionalClassMethods,properties,size,flags,extendedMethodTypes)
5._ivar_t 成员变量结构体(offset,name,type,size)
6.类的实例结构体(class_ro_t 存储的大多是类在编译时就已经确定的信息。(区别于class_rw_t, 提供了运行时对类拓展的能力)。)
7.类本身的结构体(isa; //元类的指针 superclass;//父类的指针 cache //缓存 vtable
ro:指向常量的指针,其中存储了当前类在编译期就已经确定的属性、方法以及遵循的协议。 )
8.类扩展的结构体
( name; //名称
cls; //哪个类的扩展
instance_methods;//实例方法列表
class_methods;//类方法列表
protocols;//协议列表
properties;//属性列表)