内容列表

  • 对象模型(结构定义,类对象、元类和实例对象的关系)
  • 消息传递和转发机制
  • runtime系统功能理解

对象模型

结构定义

对象(Object): OC中基本构造单元 (building block),用于存储和传递数据。

能够在objc.h的文件里查找到对象结构的定义,例如以下所看到的即对象结构为Class类型的isa,而Class是 objc_class结构类型指针。

objc_class即我们理解的类对象结构。其也包含一个isa类对象结构指针。

类和对象的终于实现都是一种数据结构,(subclass is an instance of superclass)

  • 对象结构
  1. /// Represents an instance of a class.
  2. struct objc_object {
  3. Class isa OBJC_ISA_AVAILABILITY;
  4. };
  • id类型定义
  1. /// A pointer to an instance of a class.
  2. typedef struct objc_object *id;
  • Class类型定义
  1. /// An opaque type that represents an Objective-C class.
  2. typedef struct objc_class *Class;
  • 类(对象)结构
  1. struct objc_class {
  2. Class isa OBJC_ISA_AVAILABILITY;
  3. #if !__OBJC2__
  4. Class super_class OBJC2_UNAVAILABLE;
  5. const char *name OBJC2_UNAVAILABLE;
  6. long version OBJC2_UNAVAILABLE;
  7. long info OBJC2_UNAVAILABLE;
  8. long instance_size OBJC2_UNAVAILABLE;
  9. struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
  10. struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
  11. struct objc_cache *cache OBJC2_UNAVAILABLE;
  12. struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
  13. #endif
  14. } OBJC2_UNAVAILABLE;

类(类对象)、元类(元类对象)和实例对象的关系

一个完整的类应该包含类方法、实例方法和成员变量(实例变量), 每一个对象都包含一个isa(is a class)指针指向类对象(执行时方法发送给对象消息,才确定类别并调用相应的方法实现)。类对象结构中记载了类的全部信息。

类对象的isa指向元类对象(meta class),类对象中的方法列表是实例方法(-, instance methods)。 元类对象中的方法列表是类方法(+, class methods)

  • 能够这么理解:

    类包含类对象和元类对象,它们通过类对象结构定义,构成类的全部信息。在定义实例对象的时候,并不会进行不论什么存储空间(堆)分配,直到调用类方法alloc函数和实例方法init函数实现实例对象在堆中的结构存储分配。并将isa指向其类对象。父类成员变量和相应类对象成员变量初始化为0或nil

上述理解能够通过以下代码和对象变量结构分析来进行确认。

  • 測试代码
  1. #import <Foundation/Foundation.h>
  2. #import <objc/runtime.h>
  3. @interface AClass : NSObject
  4. {
  5. int a;
  6. char cA;
  7. }
  8. - (void)printA;
  9. @end
  10. @implementation AClass
  11. - (void)printA
  12. {
  13. NSLog(@"I am class A~");
  14. }
  15. @end
  16. @interface BClass : AClass
  17. {
  18. int b;
  19. char cB;
  20. }
  21. - (void)printB;
  22. @end
  23. @implementation BClass
  24. - (void)printB
  25. {
  26. NSLog(@"I am class B~");
  27. }
  28. @end
  29. // ---------- main ----------
  30. int main(int argc, const char * argv[]) {
  31. @autoreleasepool {
  32. // ******对象模型初探******
  33. AClass *a = [[AClass alloc] init];
  34. BClass *b = [[BClass alloc] init];
  35. BClass *b1;
  36. [a printA];
  37. [b printB];
  38. }
  39. return 0;
  40. }
  • 查看对象变量结构(通过设置断点进入Debug模式查看)

  • 类对象、元类和实例对象的isa指针调用图示(subclass is a instance of superclass)

(1) Root class 是NSObject, NSObject没有超类。superclass -> nil

(2) 每一个类对象都有一个isa指向唯一的Meta class

(3) 每一个元类对象的 isa指针都指向 NSObject的元类对象

消息传递和转发机制

消息传递(Messaging): 在对象之间传递数据并执行任务的过程

Objective-C基于C语言加入了面向对象特性和消息转发机制的动态语言。除编译器外还须要用Runtime系统来动态创建类和对象进行消息发送和转发。

不同语言有不同函数传递方法,C语言 - 函数指针,C++ - 函数调用(引用)类成员函数在编译时候就确定了其所属类别, Objective-C 通过选择器和block。

Objective-C强调消息传递而非方法调用。

能够向一个对象传递消息,且不须要再编译期声明这些消息的处理方法。

这些方法在执行时才确定。执行时(runtime)详细功能将在以下介绍。

[receiver message];

并不会立即执行 receiver 对象的 message方法的代码。而是向receiver发送一条message消息,该句话被编译器转化为:

id obj_msgSend(id self, SEL op, …);

PS: 消息调用函数还存在特殊情况,如其它函数

objc_msgSend_stret //待发送消息返回结构体

objc_msgSend_fpret //返回浮点数

objc_msgSendSuper //给超类发消息

SEL 表示方法选择器,结构例如以下: typedef struct objc_selector*SEL。, 可通过关键字@selector()获得

id 数据结构在第一部分:对象模型中已经有定义。

obj_msgSend 发消息流程:

  • 依据receiver 对象的isa类对象指针获取相应的class(类对象);
  • 优先在类对象的cache(fast map)查找message方法,Not find ->再到methodLists(类中的调度表,用于映射方法和实际内存地址。同一时候类中还包含指向父类的指针)查找;
  • 假设没有在class象里找到。再到super_class查找。
  • 假设找到message这种方法,执行它的实现IMP
  • 假设找不到消息。则执行消息转发(message forwarding)

Method数据结构 runtime.h头文件里定义:

  1. typedef struct objc_method *Method;
  2. struct objc_method {
  3. SEL method_name; // 特殊的字符串。描写叙述方法名, 能够通过关键字 @selector( ) 获取
  4. char *method_types;
  5. IMP method_imp;
  6. }

PS:消息转发分为两大阶段即动态加入方法解析(dynamic method resolution)和完整的消息转发机制(full forward mechanism)

runtime系统功能理解

runtime : 程序执行后。提供相关支持的代码叫做OC执行期环境(OC runtime),它提供了对象间传递消息的重要函数(比方objc_msgSend),而且包含创建类实例所用的全部逻辑(即创建实例对象的存储结构和空间,包含isa指向“类对象”的指针)

runtime系统是一个用C语言编写动态链接库,核心是消息分发。Runtime机制包含对象模型。消息传递和转发。方法实现机制和其它执行时方法。能够实现动态创建改动类对象和对象等功能,消息传递和转发,方法动态实现,Method Swizzling等功能。

##Objective-C程序生成目标文件里的执行时信息怎样获取?

对于一个OC的.m程序文件,在Terminal输入命令:

gcc -framework Foundation main.m -o p1

当然。执行命令即: ./p1

然后,通过 otool 工具获取目标文件(包含头部、载入指令、各个segment)中执行时信息(有专门的segment保存)

otool -o p1

PS 我们能够通过获取执行时信息了解对象模型中元类对象和类对象结构等信息,例如以下所看到的。能够清晰看到类对象列表和元类映射关系,结构信息

  1. p1:
  2. Contents of (__DATA,__objc_classlist) section
  3. 0000000100001098 0x100001310
  4. isa 0x1000012e8
  5. superclass 0x0
  6. cache 0x0
  7. vtable 0x0
  8. data 0x100001160 (struct class_ro_t *)
  9. flags 0x0
  10. instanceStart 8
  11. instanceSize 13
  12. reserved 0x0
  13. ivarLayout 0x0
  14. name 0x100000f60 AClass
  15. baseMethods 0x1000010f8 (struct method_list_t *)
  16. entsize 24
  17. count 1
  18. name 0x100000f6e printA
  19. types 0x100000f91 v16@0:8
  20. imp 0x100000d90
  21. baseProtocols 0x0
  22. ivars 0x100001118
  23. entsize 32
  24. count 2
  25. offset 0x1000012c8 8
  26. name 0x100000f75 a
  27. type 0x100000f99 i
  28. alignment 2
  29. size 4
  30. offset 0x1000012d0 12
  31. name 0x100000f77 cA
  32. type 0x100000f9b c
  33. alignment 0
  34. size 1
  35. weakIvarLayout 0x0
  36. baseProperties 0x0
  37. Meta Class
  38. isa 0x0
  39. superclass 0x0
  40. cache 0x0
  41. vtable 0x0
  42. data 0x1000010b0 (struct class_ro_t *)
  43. flags 0x1 RO_META
  44. instanceStart 40
  45. instanceSize 40
  46. reserved 0x0
  47. ivarLayout 0x0
  48. name 0x100000f60 AClass
  49. baseMethods 0x0 (struct method_list_t *)
  50. baseProtocols 0x0
  51. ivars 0x0
  52. weakIvarLayout 0x0
  53. baseProperties 0x0
  54. 00000001000010a0 0x100001360
  55. isa 0x100001338
  56. superclass 0x100001310
  57. cache 0x0
  58. vtable 0x0
  59. data 0x100001258 (struct class_ro_t *)
  60. flags 0x0
  61. instanceStart 16
  62. instanceSize 21
  63. reserved 0x0
  64. ivarLayout 0x0
  65. name 0x100000f67 BClass
  66. baseMethods 0x1000011f0 (struct method_list_t *)
  67. entsize 24
  68. count 1
  69. name 0x100000f7a printB
  70. types 0x100000f91 v16@0:8
  71. imp 0x100000dc0
  72. baseProtocols 0x0
  73. ivars 0x100001210
  74. entsize 32
  75. count 2
  76. offset 0x1000012d8 16
  77. name 0x100000f81 b
  78. type 0x100000f99 i
  79. alignment 2
  80. size 4
  81. offset 0x1000012e0 20
  82. name 0x100000f83 cB
  83. type 0x100000f9b c
  84. alignment 0
  85. size 1
  86. weakIvarLayout 0x0
  87. baseProperties 0x0
  88. Meta Class
  89. isa 0x0
  90. superclass 0x1000012e8
  91. cache 0x0
  92. vtable 0x0
  93. data 0x1000011a8 (struct class_ro_t *)
  94. flags 0x1 RO_META
  95. instanceStart 40
  96. instanceSize 40
  97. reserved 0x0
  98. ivarLayout 0x0
  99. name 0x100000f67 BClass
  100. baseMethods 0x0 (struct method_list_t *)
  101. baseProtocols 0x0
  102. ivars 0x0
  103. weakIvarLayout 0x0
  104. baseProperties 0x0
  105. Contents of (__DATA,__objc_classrefs) section
  106. 00000001000012b8 0x100001310
  107. 00000001000012c0 0x100001360
  108. Contents of (__DATA,__objc_imageinfo) section
  109. version 0
  110. flags 0x0

參考资源

Effective Objective-C 2.0

Objective-C的对象模型与执行时

深入理解Objective-C的Runtime机制

Objective-C的动态特性

Objective-C的对象模型和runtime机制的更多相关文章

  1. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 Windows Phone

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 Windows Phone         和.NET托管代码和 ...

  2. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 client对象模型API范围

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 client对象模型API范围         本章之前提到过. ...

  3. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 client对象模型(CSOM)基础

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览  client对象模型(CSOM)基础         在SP2 ...

  4. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 介绍SP2013中远程APIs

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览  介绍SP2013中远程APIs         当SP首次開始 ...

  5. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 JavaScript

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览  JavaScript         与托管.NETclien ...

  6. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 托管代码(.NET)

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览  托管代码(.NET)         在SP2010中,微软提 ...

  7. c++对象模型和RTTI(runtime type information)

    在前面已经探讨过了虚继承对类的大小的影响,这次来加上虚函数和虚继承对类的大小的影响. 先来回顾一下之前例子的代码: #include <iostream> using namespace ...

  8. javascript对象模型和function对象

    javascript中,函数就是对象 <html> <head> <script type="text/javascript"> functio ...

  9. BOM浏览器对象模型和API速查

    什么是BOMBOM是Browser Object Model的缩写,简称浏览器对象模型BOM提供了独立于内容而与浏览器窗口进行交互的对象由于BOM主要用于管理窗口与窗口之间的通讯,因此其核心对象是wi ...

随机推荐

  1. 让pre标签自动换行示例代码

    pre 元素可定义预格式化的文本.被包围在 pre 元素中的文本通常会保留空格和换行符.而文本也会呈现为等宽字体. <pre> 标签的一个常见应用就是用来表示计算机的源代码.对于技术博客经 ...

  2. STL1-unordered_map

    最近几天我要整理一下遇到的STL的函数,本来其实我是没有打算学的,认为用C就完全可以实现,干嘛要记那么多复杂的函数呢,所以我之前的做法都是将常用的C函数自己做了一个lib库,使用起来也是蛮方便的呢,但 ...

  3. 进入appstore中指定的应用

    1.进入appstore中指定的应用 NSString *str = [NSString stringWithFormat:                           @"itms ...

  4. c++ struct 使用

     typedef与结构结合使用 typedef struct tagMyStruct{  int iNum; long lLength;} MyStruct; 这语句实际上完成两个操作: 1) 定义一 ...

  5. [POJ] #1003# Hangover : 浮点数运算

    一. 题目 Hangover Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 116593   Accepted: 56886 ...

  6. InfiniBand

    Mellanox InfiniBand卡线缆性能延迟性测试程序源码,C源码实现操作mysql库,实现简单的增删改查,代码当前用的是增插入20000条数据 具体见源码 #include <mysq ...

  7. Linux下oracle导入(exp)导出(imp)出现"Failed to open ...for reader/write"错误

  8. Python字典 (dictionary)

    字典dict,是Python唯一的标准mapping类型,也是内置在Python解释器中的. mapping object把一个可哈希的值(hashable value)映射到一个任意的object上 ...

  9. 30几个HTML5经典动画应用回顾 让你大饱眼福

    周末大放送,让我们来回顾一下HTML5经典动画应用,一定会让你大饱眼福. 1.HTML5 Canvas画板画图工具 可定义笔刷和画布 HTML5 Canvas还有一个比较实用的应用,那就是网络画板,这 ...

  10. POJ1014Dividing(DP)

    http://poj.org/problem?id=1014 最简单之多重背包 #include <map> #include <set> #include <stack ...