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;//属性列表)
上一篇下一篇

猜你喜欢

热点阅读