订单

来源:互联网 发布:淘宝账号免费注册 编辑:程序博客网 时间:2024/04/27 13:31

<style type="text/css" isprelink="true">@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);</style>
<style type="text/css">@import url(/css/cuteeditor.css);</style>
<style type="text/css" isprelink="true">@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);</style>
<style type="text/css">@import url(/css/cuteeditor.css);</style>
<style type="text/css" isprelink="true">@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);</style>
<style type="text/css">@import url(/css/cuteeditor.css);</style>
<p style="text-align: center">Runtime系统是一个由一系列C语言函数和数据结构组成的动态共享库,即通过面向过程语言C实现Objective-C语言的面向对象特性。 </p>
<p><span style="font-size: 15pt"><strong><span style="font-family: Times New Roman">1 </span><span style="font-family: 宋体">、概述</span><span style="font-family: Times New Roman"> </span></strong></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #a09916; font-size: 10pt"><strong>Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理。</strong></span>这种特性意味着Objective-C不仅需要一个编译器,还需要一个运行时系统来执行编译的代码。对于Objective-C来说,这个运行时系统就像一个操作系统一样:它让所有的工作可以正常的运行,这个运行时系统即Objc Runtime。Objc Runtime其实是一个Runtime库,它基本上是<span style="color: #a09916; font-size: 10pt"><strong>用C</strong></span><span style="font-size: 9pt">和</span><span style="color: #a09916; font-size: 10pt"><strong>汇编</strong></span><span style="font-size: 9pt">写的</span>,<span style="color: #a09916"><span style="font-size: 10pt"><strong>这个库使得<span style="color: red">C语言<span style="color: #a09916">有了<span style="color: red">面向对象的能力</span></span></span></strong></span>。</span> </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Objective-C runtime目前有两个版本: </p>
<p style="text-align: justify"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1) Modern Runtime :在Objective-C 2.0 引进,覆盖了64位的Mac OS X Apps,还有 iOS Apps; </span></p>
<p style="text-align: justify"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp; &nbsp; 2) Legacy Runtime 是早期用来给32位 Mac OS X Apps 用的,也就是可以不用管就是了。 </span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这两个版本最大的区别在于当你更改一个类的实例变量的布局时,在早期版本中你需要重新编译它的子类,而现行版就不需要。 </p>
<p><span style="font-size: 15pt"><strong><span style="font-family: Times New Roman">2</span><span style="font-family: 宋体">、类与对象</span><span style="font-family: Times New Roman"> </span></strong></span></p>
<p><span style="font-size: 12pt"><strong><span style="font-family: Times New Roman">2.1 </span><span style="font-family: 宋体">面向对象模型</span><span style="font-family: Times New Roman"> </span></strong></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在面向对象编程模型中,主要围绕两种结构进行设计和编程:类与对象。 </p>
<p><strong><span style="font-family: Times New Roman">2.1.1 </span><span style="font-family: 宋体">对象</span><span style="font-family: Times New Roman"> </span></strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对象是人们要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象,它不仅能表示具体的事物,还能表示抽象的规则、计划或事件。 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对象实现了数据和操作的结合,使数据和操作封装于对象的统一体中: </p>
<p style="text-align: justify"><span style="font-size: 10pt"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;1) 数据:</strong>一个对象用数据值来描述它的状态。 </span></p>
<p style="text-align: justify"><span style="font-size: 10pt"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2) 操作:</strong>用于改变对象的状态,对象及其操作就是对象的行为。 </span></p>
<p><strong><span style="font-family: Times New Roman">2.1.2 </span><span style="font-family: 宋体">类</span><span style="font-family: Times New Roman"> </span></strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 具有相同特性(数据元素)和行为(功能)的对象的抽象就是类。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象,类实际上就是一种数据类型。 </p>
<p><span style="font-size: 12pt"><strong><span style="font-family: Times New Roman">2.2 </span><span style="font-family: 宋体">数据结构</span><span style="font-family: Times New Roman"> </span></strong></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 由于Objective-C底层是通过C语言实现,但C语言又不存在类和对象。为了描述面向对象的特性,所以Objective-C使用C语言的<span style="color: red; font-size: 10pt"><strong>结构体</strong></span>来表示<span style="color: red; font-size: 10pt"><strong>类</strong></span>和<span style="color: red; font-size: 10pt"><strong>对象</strong></span>,即Objective-C语言中的类和对象本身是由结构体表示。 </p>
<p><strong><span style="font-family: Times New Roman">2.2.1 </span><span style="font-family: 宋体">类结构</span><span style="font-family: Times New Roman"> </span></strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Objective-C的类是由Class类型来表示的,它实际上是一个指向objc_class结构体的指针。可以在[3]项目Public Headers/runtime.h目录下发现有如下定义: </p>
<p style="text-align: center"><span style="font-size: 9pt">定义 21:objc_class结构体 </span></p>
<div>
<table style="background-color: #f2dbdb; border-collapse: collapse" border="0" align="center">
    <colgroup>
    <col style="width: 590px"></colgroup>
    <tbody valign="top">
        <tr style="height: 23px">
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="color: #aa0d91; font-size: 9pt">typedef<span style="color: black"> <span style="color: #aa0d91">struct<span style="color: black"> objc_class *<span style="color: red"><strong>Class</strong><span style="color: black">;</span></span></span></span></span></span></p>
            </td>
        </tr>
        <tr>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="color: #aa0d91; font-size: 9pt">struct<span style="color: black"> <span style="color: red"><strong>objc_class</strong><span style="color: black"> </span></span></span></span></p>
            <p><span style="color: black; font-size: 9pt">{ </span></p>
            <p><span style="color: black; font-size: 9pt"><span style="color: red"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class isa</strong><span style="color: black"> OBJC_ISA_AVAILABILITY; </span></span></span></p>
            <p><span style="color: #643820; font-size: 9pt">#if !__OBJC2__ </span></p>
            <p><span style="color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class super_class <span style="color: #e36c0a"><strong>//父类</strong><span style="color: black"> </span></span></span></p>
            <p><span style="color: black; font-size: 9pt"><span style="color: #aa0d91"><span style="color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>const<span style="color: black"> <span style="color: #aa0d91">char<span style="color: black"> *name <span style="color: #e36c0a"><strong>//类名</strong><span style="color: black"> </span></span></span></span></span></span></span></p>
            <p><span style="color: black; font-size: 9pt"><span style="color: #aa0d91"><span style="color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>long<span style="color: black"> version <span style="color: #e36c0a"><strong>//类的版本信息,默认为0</strong><span style="color: black"> </span></span></span></span></span></p>
            <p><span style="color: black; font-size: 9pt"><span style="color: #aa0d91"><span style="color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>long<span style="color: black"> info <span style="color: #e36c0a"><strong>//类信息,供运行期使用的一些位标识</strong><span style="color: black"> </span></span></span></span></span></p>
            <p><span style="color: black; font-size: 9pt"><span style="color: #aa0d91"><span style="color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>long<span style="color: black"> instance_size <span style="color: #e36c0a"><strong>//该类的实例变量大小</strong><span style="color: black"> </span></span></span></span></span></p>
            <p><span style="color: black; font-size: 9pt"><span style="color: #aa0d91"><span style="color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>struct<span style="color: black"> objc_ivar_list *ivars <span style="color: #e36c0a"><strong>//该类的成员变量链表</strong><span style="color: black"> </span></span></span></span></span></p>
            <p><span style="color: black; font-size: 9pt"><span style="color: #aa0d91"><span style="color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>struct<span style="color: black"> objc_method_list **methodLists <span style="color: #e36c0a"><strong>//方法定义的链表 </strong><span style="color: black"></span></span></span></span></span></p>
            <p><span style="color: black; font-size: 9pt"><span style="color: #aa0d91"><span style="color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>struct<span style="color: black"> objc_cache *cache <span style="color: #e36c0a"><strong>//方法缓存 </strong><span style="color: black"></span></span></span></span></span></p>
            <p><span style="color: black; font-size: 9pt"><span style="color: #aa0d91"><span style="color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>struct<span style="color: black"> objc_protocol_list *protocols <span style="color: #e36c0a"><strong>//协议链表</strong><span style="color: black"> </span></span></span></span></span></p>
            <p><span style="color: #643820; font-size: 9pt">#endif </span></p>
            <p><span style="color: black; font-size: 9pt">} OBJC2_UNAVAILABLE;</span></p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p>在这个定义中,下面几个字段是我们感兴趣的 </p>
<p style="text-align: justify"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1) isa:需要注意的是在Objective-C中,所有的类自身也是一个对象,这个对象的Class里面也有一个isa指针,它指向metaClass(元类),在后面会介绍它。 </span></p>
<p style="text-align: justify"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2) super_class:指向该类的父类,如果该类已经是最顶层的根类(如NSObject或NSProxy),则super_class为NULL。 </span></p>
<p><strong><span style="font-family: Times New Roman">2.2.2 </span><span style="font-family: 宋体">对象结构</span><span style="font-family: Times New Roman"> </span></strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在Objective-C中的对象由objc_object结构体表示,它的定义如下(objc/objc.h): </p>
<p style="text-align: center"><span style="font-size: 9pt">定义 22:objc_object结构体 </span></p>
<div>
<table style="background-color: #f2dbdb; border-collapse: collapse" border="0" align="center">
    <colgroup>
    <col style="width: 590px"></colgroup>
    <tbody valign="top">
        <tr>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="color: #aa0d91; font-size: 9pt">struct<span style="color: black"> objc_object </span></span></p>
            <p><span style="color: black; font-size: 9pt">{ </span></p>
            <p><span style="color: black; font-size: 9pt"><span style="color: red"><strong><span style="color: black; font-size: 9pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Class isa</strong><span style="color: black"> OBJC_ISA_AVAILABILITY; </span></span></span></p>
            <p><span style="color: black; font-size: 9pt">};</span></p>
            </td>
        </tr>
        <tr>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="color: #aa0d91; font-size: 9pt">typedef<span style="color: black"> <span style="color: #aa0d91">struct<span style="color: black"> objc_object *<span style="color: #aa0d91">id<span style="color: black">;</span></span></span></span></span></span></p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 可以看到,这个结构体只有一个成员,即指向其类的isa指针。这样,当向一个Objective-C对象发送消息时,运行时库会根据实例对象的isa指针找到这个实例对象所属的类。Runtime库会在类的方法列表及父类的方法列表中去寻找与消息对应的selector指向的方法。找到后即运行这个方法。 </p>
<p><span style="font-size: 12pt"><strong><span style="font-family: Times New Roman">2.3 Objective-C</span><span style="font-family: 宋体">设计模型</span><span style="font-family: Times New Roman"> </span></strong></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C++模型中有两种结构:静态成员和非静态成员。静态成员属于整个类所有的对象包括类,任何对象都可以操作;而非静态成员只属于实例化后的某个对象,是对象所独有的,若未实例化则无法访问。 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 类似C++模型,Objective-C模型也有两种操作实例的方式:实例方法和类方法。若要操作实例方法需要将类进行实例化为对象,然后通过对象来操作方法;若要操作类方法,则不需要实现化,直接通过类即可操作类方法。 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 由于Objective-C模型存在实例操作方法和类操作方法,所以runtime系统需要某种方式来存储这两种方法: </p>
<p style="text-align: justify"><span style="font-size: 10pt"><span style="color: red"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1) 对象实例:</strong></span>该实例只是一种连续的二进制数据流(即void*类型),用于存放对象中的数据(即Objective-C成员变量),并且对象实例的二进制数据流中第一个数据类型永远为objc_class指针(命名为isa),之后才存放其它数据成员,之后其它数据成员占多大的字节由类实例(即objc_class对象)类定义。 </span></p>
<p style="text-align: justify"><span style="font-size: 10pt"><span style="color: red"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2)类实例:</strong></span>该实例是objc_class结构体的实例化对象,是对象实例的一种"导航",其存放对象实例的所有信息,包括二进制数据流的分配和对象实例提供的操作方法等各种。 </span></p>
<p style="text-align: justify"><span style="font-size: 10pt"><span style="color: red"><strong>&nbsp;&nbsp;&nbsp; 3)元类实例:</strong></span>该实例也是objc_class结构体的实例化对象,不同的是该实例是类实例的"导航",其存放类实例的所有信息,当要操作类方法时,就通过元类实例来操作类实例。 </span></p>
<p>&nbsp;</p>
<p style="text-align: center"></p>
<div align="center"><img style="width: 511px; height: 64px" alt="" src="http://images2015.cnblogs.com/blog/499013/201604/499013-20160424095407226-150451552.png" width="919" height="129" /></div>
<p align="center">&nbsp;<span style="font-size: 9pt">图 21 Objective-C实例关系图 </span></p>
<p>&nbsp;<strong><span style="font-family: Times New Roman">2.3.1 </span><span style="font-family: 宋体">对象实例</span><span style="font-family: Times New Roman"> </span></strong></p>
<p><strong><span style="font-family: Times New Roman">2.3.1.1 </span><span style="font-family: 宋体">内存空间布局</span><span style="font-family: Times New Roman"> </span></strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;对象实例其实是一种连续的二进制数据流(即void*类型),其存放两种内容:objc_class指针和Objective-C对象的所有数据。而对象数据如何在二进制数据中组织,及对象的操作方法则存放在类实例中,并且创建的对象实例的大小由类实例中的instance_size值决定。 </p>
<p style="text-align: center"></p>
<div align="center"><img style="width: 127px; height: 98px" alt="" src="http://images2015.cnblogs.com/blog/499013/201604/499013-20160424095718663-992565854.png" width="127" height="98" /></div>
<p align="center">&nbsp;<span style="font-size: 9pt">图 22 对象实例内存空间布局 </span></p>
<p>如创建创建一个MyClass对象,其内存空间布局如表 21所示: </p>
<div>
<table style="background-color: #fde9d9; border-collapse: collapse" border="0" align="center">
    <colgroup>
    <col style="width: 590px"></colgroup>
    <tbody valign="top">
        <tr>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="color: #aa0d91; font-size: 9pt">@interface<span style="color: black"> MyClass </span></span></p>
            <p><span style="color: black; font-size: 9pt">{ </span></p>
            <p><span style="color: black; font-size: 9pt">int age; </span></p>
            <p><span style="color: black; font-size: 9pt">float height; </span></p>
            <p><span style="color: black; font-size: 9pt">} </span></p>
            <p><span style="color: #aa0d91; font-size: 9pt">@end</span></p>
            </td>
        </tr>
        <tr>
            <td style="padding-left: 7px; padding-right: 7px">&nbsp;</td>
        </tr>
    </tbody>
</table>
</div>
<p>&nbsp;</p>
<p style="text-align: center"><span style="font-size: 9pt">表 21 MyClass对象实例的内存布局 </span></p>
<div style="text-align: center">
<table style="border-collapse: collapse" border="0" align="center">
    <colgroup>
    <col style="width: 54px">
    <col style="width: 101px">
    <col style="width: 101px"></colgroup>
    <tbody valign="top">
        <tr style="background: #4f81bd; height: 22px">
            <td style="padding-left: 7px; padding-right: 7px" valign="middle">
            <p style="text-align: center"><span style="color: white; font-size: 12pt"><strong>序号</strong></span></p>
            </td>
            <td style="padding-left: 7px; padding-right: 7px" valign="middle">
            <p style="text-align: center"><span style="color: white; font-size: 12pt"><strong>成员</strong></span></p>
            </td>
            <td style="padding-left: 7px; padding-right: 7px" valign="middle">
            <p style="text-align: center"><span style="color: white; font-size: 12pt"><strong>字节占用大小</strong></span></p>
            </td>
        </tr>
        <tr style="background: #dbe5f1; height: 22px">
            <td style="padding-left: 7px; padding-right: 7px" valign="middle">
            <p style="text-align: center"><span style="font-size: 12pt"><strong>0</strong></span>&nbsp;</p>
            </td>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="font-size: 12pt">objc_class *isa</span></p>
            </td>
            <td style="padding-left: 7px; padding-right: 7px" valign="middle">
            <p style="text-align: center"><span style="font-size: 12pt">8</span></p>
            </td>
        </tr>
        <tr style="height: 22px">
            <td style="padding-left: 7px; padding-right: 7px" valign="middle">
            <p style="text-align: center"><span style="font-size: 12pt"><strong>1</strong></span>&nbsp;</p>
            </td>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="font-size: 12pt">int age</span></p>
            </td>
            <td style="padding-left: 7px; padding-right: 7px" valign="middle">
            <p style="text-align: center"><span style="font-size: 12pt">4</span>&nbsp;</p>
            </td>
        </tr>
        <tr style="background: #dbe5f1; height: 22px">
            <td style="padding-left: 7px; padding-right: 7px" valign="middle">
            <p style="text-align: center"><span style="font-size: 12pt"><strong>2</strong></span>&nbsp;</p>
            </td>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="font-size: 12pt">float height</span></p>
            </td>
            <td style="padding-left: 7px; padding-right: 7px" valign="middle">
            <p style="text-align: center"><span style="font-size: 12pt">4</span>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p>&nbsp;<strong><span style="font-family: Times New Roman">2.3.1.2 </span><span style="font-family: 宋体">创建对象实例</span><span style="font-family: Times New Roman"> </span></strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;当创建Objective-C对象时,runtime通过malloc创建一块堆空间,然后再强制转换为objc_object*类型,最后初始化其isa。可在runtime.h文件中发现其创建的过程:class_createInstance() --&gt; _class_createInstance() --&gt; _class_createInstanceFromZone() </p>
<div>
<div class="cnblogs_code">
<div><span style="color: #008080">&nbsp;1</span>&nbsp;id&nbsp;&nbsp;_class_createInstanceFromZone(Class&nbsp;cls,&nbsp;size_t&nbsp;extraBytes,&nbsp;<span style="color: #0000ff">void</span>&nbsp;*zone)<br />
<span style="color: #008080">&nbsp;2</span>&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;...<br />
<span style="color: #008080">&nbsp;3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size&nbsp;=&nbsp;cls-&gt;alignedInstanceSize()&nbsp;+&nbsp;extraBytes;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">获取对象实例的空间大小</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;4</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;bytes&nbsp;=&nbsp;calloc(<span style="color: #800080">1</span>,&nbsp;size);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">创建内存空间</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;5</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;...<br />
<span style="color: #008080">&nbsp;6</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">return</span>&nbsp;objc_constructInstance(cls,&nbsp;bytes);<br />
<span style="color: #008080">&nbsp;7</span>&nbsp;}<br />
<span style="color: #008080">&nbsp;8</span>&nbsp;id&nbsp;&nbsp;objc_constructInstance(Class&nbsp;cls,&nbsp;<span style="color: #0000ff">void</span>&nbsp;*bytes)&nbsp;<br />
<span style="color: #008080">&nbsp;9</span>&nbsp;{<br />
<span style="color: #008080">10</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br />
<span style="color: #008080">11</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id&nbsp;obj&nbsp;=&nbsp;(id)bytes;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">将void*类型强制转换为objc_object*类型</span><span style="color: #008000"><br />
</span><span style="color: #008080">12</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;obj-&gt;initIsa(cls);&nbsp;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">初始化objc_object结构体中的isa成员</span><span style="color: #008000"><br />
</span><span style="color: #008080">13</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<span style="color: #008080">14</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">return</span>&nbsp;obj;<br />
<span style="color: #008080">15</span>&nbsp;}</div>
</div>
</div>
<p>&nbsp;<strong><span style="font-family: Times New Roman">2.3.1.3 </span><span style="font-family: 宋体">访问成员变量</span><span style="font-family: Times New Roman"> </span></strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 访问成员变量首先通过对象实例中的isa指针,获取objc_class对象中指定变量的信息;然后再访问对象实例中的某块内存。 </p>
<p style="text-align: justify"><span style="font-size: 10pt"><strong>&nbsp;&nbsp;&nbsp;&nbsp; 1) 获取变量信息 </strong></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;变量的信息都存储在类实例(即objc_class对象)中,所以根据对象实例(即objc_object对象)中的isa指针索引到类实例,然后遍历类实例中定义了变量。可在runtime.h文件中的 class_getInstanceVariable方法查看其过程: </p>
<div>
<div class="cnblogs_code">
<div><span style="color: #008080">&nbsp;1</span>&nbsp;Ivar&nbsp;class_getInstanceVariable(Class&nbsp;cls,&nbsp;<span style="color: #0000ff">const</span>&nbsp;<span style="color: #0000ff">char</span>&nbsp;*name)<br />
<span style="color: #008080">&nbsp;2</span>&nbsp;{<br />
<span style="color: #008080">&nbsp;3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">if</span>&nbsp;(!cls&nbsp;&nbsp;||&nbsp;&nbsp;!name)&nbsp;<span style="color: #0000ff">return</span>&nbsp;nil;<br />
<span style="color: #008080">&nbsp;4</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">return</span>&nbsp;_class_getVariable(cls,&nbsp;name,&nbsp;nil);<br />
<span style="color: #008080">&nbsp;5</span>&nbsp;}<br />
<span style="color: #008080">&nbsp;6</span>&nbsp;Ivar&nbsp;_class_getVariable(Class&nbsp;cls,&nbsp;<span style="color: #0000ff">const</span>&nbsp;<span style="color: #0000ff">char</span>&nbsp;*name,&nbsp;Class&nbsp;*memberOf)<br />
<span style="color: #008080">&nbsp;7</span>&nbsp;{<br />
<span style="color: #008080">&nbsp;8</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">for</span>&nbsp;(;&nbsp;cls&nbsp;!=&nbsp;Nil;&nbsp;cls&nbsp;=&nbsp;cls-&gt;superclass)&nbsp;{&nbsp;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">遍历继承结构所有的变量</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;9</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">int</span>&nbsp;i;<br />
<span style="color: #008080">10</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">for</span>&nbsp;(i&nbsp;=&nbsp;<span style="color: #800080">0</span>;&nbsp;i&nbsp;&lt;&nbsp;cls-&gt;ivars-&gt;ivar_count;&nbsp;i++)&nbsp;{<br />
<span style="color: #008080">11</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;old_ivar&nbsp;*ivar&nbsp;=&nbsp;&amp;cls-&gt;ivars-&gt;ivar_list[i];<br />
<span style="color: #008080">12</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">if</span>&nbsp;(ivar-&gt;ivar_name&nbsp;&nbsp;&amp;&amp;&nbsp;&nbsp;<span style="color: #800080">0</span>&nbsp;==&nbsp;strcmp(name,&nbsp;ivar-&gt;ivar_name))&nbsp;{&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">比较是否与指定的变量相同</span><span style="color: #008000"><br />
</span><span style="color: #008080">13</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">if</span>&nbsp;(memberOf)&nbsp;*memberOf&nbsp;=&nbsp;cls;<br />
<span style="color: #008080">14</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">return</span>&nbsp;(Ivar)ivar;<br />
<span style="color: #008080">15</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080">16</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080">17</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080">18</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">return</span>&nbsp;nil;<br />
<span style="color: #008080">19</span>&nbsp;}</div>
</div>
</div>
<p>&nbsp;<span style="font-size: 10pt"><strong>&nbsp;&nbsp;&nbsp;&nbsp; 2) 获取实例内容 </strong></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 根据objc_class对象中定义的变量信息,可计算出变量的偏移量,从而获取变量的地址,最后可获取或设置objc_object对象中的变量值。如runtime.h文件中的object_getIvar和object_setIvar方法: </p>
<div class="cnblogs_code">
<div><span style="color: #008080">&nbsp;1</span>&nbsp;id&nbsp;object_getIvar(id&nbsp;obj,&nbsp;Ivar&nbsp;ivar)<br />
<span style="color: #008080">&nbsp;2</span>&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br />
<span style="color: #008080">&nbsp;3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ptrdiff_t&nbsp;ivar_offset&nbsp;=&nbsp;ivar_getOffset(ivar);&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">获取变量的偏移量</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;4</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id&nbsp;*idx&nbsp;=&nbsp;(id&nbsp;*)((<span style="color: #0000ff">char</span>&nbsp;*)obj&nbsp;+&nbsp;ivar_offset);&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">计算变量的起始地址,并强制转换为id*类型。</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;5</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br />
<span style="color: #008080">&nbsp;6</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">return</span>&nbsp;*idx;<br />
<span style="color: #008080">&nbsp;7</span>&nbsp;&nbsp;}<br />
<span style="color: #008080">&nbsp;8</span>&nbsp;<span style="color: #0000ff">void</span>&nbsp;object_setIvar(id&nbsp;obj,&nbsp;Ivar&nbsp;ivar,&nbsp;id&nbsp;value)<br />
<span style="color: #008080">&nbsp;9</span>&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br />
<span style="color: #008080">10</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ptrdiff_t&nbsp;ivar_offset&nbsp;=&nbsp;ivar_getOffset(ivar);&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">获取变量的偏移量</span><span style="color: #008000"><br />
</span><span style="color: #008080">11</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id&nbsp;*location&nbsp;=&nbsp;(id&nbsp;*)((<span style="color: #0000ff">char</span>&nbsp;*)obj&nbsp;+&nbsp;ivar_offset);&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">计算变量的起始地址,并强制转换为id*类型。</span><span style="color: #008000"><br />
</span><span style="color: #008080">12</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br />
<span style="color: #008080">13</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*location&nbsp;=&nbsp;value;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">设置为指定值</span><span style="color: #008000"><br />
</span><span style="color: #008080">14</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br />
<span style="color: #008080">15</span>&nbsp;}</div>
</div>
<p><strong><span style="font-family: Times New Roman">2.3.2 </span><span style="font-family: 宋体">类实例</span><span style="font-family: Times New Roman"> </span></strong></p>
<p><strong><span style="font-family: Times New Roman">2.3.2.1 </span><span style="font-family: 宋体">内存空间布局</span><span style="font-family: Times New Roman"> </span></strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 类实例是objc_class结构体的实例化对象,若创建的类是基类,则创建实例大小为sizeof(objc_class);若创建的类不是基类,则其实例创建的内存空间大小是由isa指针的元类(即objc_class对象)决定。 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 其中每个Objective-C类只实例化一个类实例,所有该类型的对象实例中的isa指针都指向该类实例。一般由编译器自动实例化。如下所示,不同的对象拥有同一个类实例: </p>
<div class="cnblogs_code">
<div><span style="color: #008080">&nbsp;1</span>&nbsp;-(<span style="color: #0000ff">void</span>)testMetaClass<br />
<span style="color: #008080">&nbsp;2</span>&nbsp;{<br />
<span style="color: #008080">&nbsp;3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyClass&nbsp;*myClass1&nbsp;=&nbsp;[[MyClass&nbsp;alloc]&nbsp;init];<br />
<span style="color: #008080">&nbsp;4</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class&nbsp;isa1&nbsp;=&nbsp;[myClass1&nbsp;<span style="color: #0000ff">class</span>];<br />
<span style="color: #008080">&nbsp;5</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">object1&nbsp;is&nbsp;%p.</span><span style="color: #800000">"</span>,&nbsp;myClass1);<br />
<span style="color: #008080">&nbsp;6</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">object1&nbsp;isa&nbsp;pointer:&nbsp;%p</span><span style="color: #800000">"</span>,&nbsp;isa1);<br />
<span style="color: #008080">&nbsp;7</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<span style="color: #008080">&nbsp;8</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyClass&nbsp;*myClass2&nbsp;=&nbsp;[[MyClass&nbsp;alloc]&nbsp;init];<br />
<span style="color: #008080">&nbsp;9</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class&nbsp;isa2&nbsp;=&nbsp;[myClass2&nbsp;<span style="color: #0000ff">class</span>];<br />
<span style="color: #008080">10</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">object2&nbsp;is&nbsp;%p.</span><span style="color: #800000">"</span>,&nbsp;myClass2);<br />
<span style="color: #008080">11</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">object2&nbsp;isa&nbsp;pointer:&nbsp;%p</span><span style="color: #800000">"</span>,&nbsp;isa2);<br />
<span style="color: #008080">12</span>&nbsp;}<br />
<span style="color: #008080">13</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">18</span>&nbsp;<span style="color: #800080">20</span>:<span style="color: #800080">30</span>:<span style="color: #800080">02.808</span>&nbsp;runtimeProject[<span style="color: #800080">1052</span>:<span style="color: #800080">78156</span>]&nbsp;object1&nbsp;<span style="color: #0000ff">is</span>&nbsp;<span style="color: #800080">0x7fda02c1d100</span>.<br />
<span style="color: #008080">14</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">18</span>&nbsp;<span style="color: #800080">20</span>:<span style="color: #800080">30</span>:<span style="color: #800080">02.808</span>&nbsp;runtimeProject[<span style="color: #800080">1052</span>:<span style="color: #800080">78156</span>]&nbsp;object1&nbsp;isa&nbsp;pointer:&nbsp;<span style="color: #800080">0x1069a13e0</span><br />
<span style="color: #008080">15</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">18</span>&nbsp;<span style="color: #800080">20</span>:<span style="color: #800080">30</span>:<span style="color: #800080">02.808</span>&nbsp;runtimeProject[<span style="color: #800080">1052</span>:<span style="color: #800080">78156</span>]&nbsp;object2&nbsp;<span style="color: #0000ff">is</span>&nbsp;<span style="color: #800080">0x7fda02d25d00</span>.<br />
<span style="color: #008080">16</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">18</span>&nbsp;<span style="color: #800080">20</span>:<span style="color: #800080">30</span>:<span style="color: #800080">02.809</span>&nbsp;runtimeProject[<span style="color: #800080">1052</span>:<span style="color: #800080">78156</span>]&nbsp;object2&nbsp;isa&nbsp;pointer:&nbsp;<span style="color: #800080">0x1069a13e0</span></div>
</div>
<p>&nbsp;<strong><span style="font-family: Times New Roman">2.3.2.2 </span><span style="font-family: 宋体">创建类实例</span><span style="font-family: Times New Roman"> </span></strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 创建类实例,同样是申请其内存空间占用的大小;然后强制转换为objc_class*;最后对类实例的成员进行初始化。可在runtime.h文件中查看objc_allocateClassPair方法创建一个<span style="color: red; font-size: 10pt"><strong>没有任何成员的类实例</strong></span>的实现: </p>
<div class="cnblogs_code">
<div><span style="color: #008080">&nbsp;1</span>&nbsp;Class&nbsp;objc_allocateClassPair(Class&nbsp;supercls,&nbsp;<span style="color: #0000ff">const</span>&nbsp;<span style="color: #0000ff">char</span>&nbsp;*name,&nbsp;&nbsp;size_t&nbsp;extraBytes)<br />
<span style="color: #008080">&nbsp;2</span>&nbsp;{<br />
<span style="color: #008080">&nbsp;3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class&nbsp;cls,&nbsp;meta;<br />
<span style="color: #008080">&nbsp;4</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">&nbsp;Allocate&nbsp;new&nbsp;classes.&nbsp;</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;5</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">if</span>&nbsp;(supercls)&nbsp;{&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">有父类</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;6</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cls&nbsp;=&nbsp;(Class)&nbsp;calloc(<span style="color: #800080">1</span>,&nbsp;supercls-&gt;ISA()-&gt;alignedInstanceSize()&nbsp;+&nbsp;extraBytes);<br />
<span style="color: #008080">&nbsp;7</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meta&nbsp;=&nbsp;(Class)&nbsp;calloc(<span style="color: #800080">1</span>,&nbsp;supercls-&gt;ISA()-&gt;ISA()-&gt;alignedInstanceSize()&nbsp;+&nbsp;extraBytes);<br />
<span style="color: #008080">&nbsp;8</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000ff">else</span>&nbsp;{&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">无父类</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;9</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cls&nbsp;=&nbsp;(Class)&nbsp;calloc(<span style="color: #800080">1</span>,&nbsp;<span style="color: #0000ff">sizeof</span>(objc_class)&nbsp;+&nbsp;extraBytes);<br />
<span style="color: #008080">10</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meta&nbsp;=&nbsp;(Class)&nbsp;calloc(<span style="color: #800080">1</span>,&nbsp;<span style="color: #0000ff">sizeof</span>(objc_class)&nbsp;+&nbsp;extraBytes);<br />
<span style="color: #008080">11</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080">12</span>&nbsp;<br />
<span style="color: #008080">13</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;objc_initializeClassPair(supercls,&nbsp;name,&nbsp;cls,&nbsp;meta);<br />
<span style="color: #008080">14</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">return</span>&nbsp;cls;<br />
<span style="color: #008080">15</span>&nbsp;}<br />
<span style="color: #008080">16</span>&nbsp;Class&nbsp;objc_initializeClassPair(Class&nbsp;supercls,&nbsp;<span style="color: #0000ff">const</span>&nbsp;<span style="color: #0000ff">char</span>&nbsp;*name,&nbsp;Class&nbsp;cls,&nbsp;Class&nbsp;meta)<br />
<span style="color: #008080">17</span>&nbsp;{<br />
<span style="color: #008080">18</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">&nbsp;Connect&nbsp;to&nbsp;superclasses&nbsp;and&nbsp;metaclasses</span><span style="color: #008000"><br />
</span><span style="color: #008080">19</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;cls-&gt;initIsa(meta);<br />
<span style="color: #008080">20</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set_superclass(cls,&nbsp;supercls,&nbsp;YES);<br />
<span style="color: #008080">21</span>&nbsp;<br />
<span style="color: #008080">22</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">&nbsp;Set&nbsp;basic&nbsp;info</span><span style="color: #008000"><br />
</span><span style="color: #008080">23</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;cls-&gt;name&nbsp;=&nbsp;strdup(name);<br />
<span style="color: #008080">24</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meta-&gt;name&nbsp;=&nbsp;strdup(name);<br />
<span style="color: #008080">25</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cls-&gt;version&nbsp;=&nbsp;<span style="color: #800080">0</span>;<br />
<span style="color: #008080">26</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meta-&gt;version&nbsp;=&nbsp;<span style="color: #800080">7</span>;<br />
<span style="color: #008080">27</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cls-&gt;info&nbsp;=&nbsp;CLS_CLASS&nbsp;|&nbsp;CLS_CONSTRUCTING&nbsp;|&nbsp;CLS_EXT&nbsp;|&nbsp;CLS_LEAF;<br />
<span style="color: #008080">28</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meta-&gt;info&nbsp;=&nbsp;CLS_META&nbsp;|&nbsp;CLS_CONSTRUCTING&nbsp;|&nbsp;CLS_EXT&nbsp;|&nbsp;CLS_LEAF;<br />
<span style="color: #008080">29</span>&nbsp;<br />
<span style="color: #008080">30</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">&nbsp;Set&nbsp;instance&nbsp;size&nbsp;based&nbsp;on&nbsp;superclass.</span><span style="color: #008000"><br />
</span><span style="color: #008080">31</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">if</span>&nbsp;(supercls)&nbsp;{<br />
<span style="color: #008080">32</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cls-&gt;instance_size&nbsp;=&nbsp;supercls-&gt;instance_size;<br />
<span style="color: #008080">33</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meta-&gt;instance_size&nbsp;=&nbsp;supercls-&gt;ISA()-&gt;instance_size;<br />
<span style="color: #008080">34</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000ff">else</span>&nbsp;{<br />
<span style="color: #008080">35</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cls-&gt;instance_size&nbsp;=&nbsp;<span style="color: #0000ff">sizeof</span>(Class);&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">&nbsp;just&nbsp;an&nbsp;isa</span><span style="color: #008000"><br />
</span><span style="color: #008080">36</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meta-&gt;instance_size&nbsp;=&nbsp;<span style="color: #0000ff">sizeof</span>(objc_class);<br />
<span style="color: #008080">37</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080">38</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<span style="color: #008080">39</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">&nbsp;No&nbsp;ivars.&nbsp;No&nbsp;methods.&nbsp;Empty&nbsp;cache.&nbsp;No&nbsp;protocols.&nbsp;No&nbsp;layout.&nbsp;Empty&nbsp;ext.</span><span style="color: #008000"><br />
</span><span style="color: #008080">40</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;cls-&gt;ivars&nbsp;=&nbsp;nil;<br />
<span style="color: #008080">41</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cls-&gt;methodLists&nbsp;=&nbsp;nil;<br />
<span style="color: #008080">42</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cls-&gt;cache&nbsp;=&nbsp;(Cache)&amp;_objc_empty_cache;<br />
<span style="color: #008080">43</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cls-&gt;protocols&nbsp;=&nbsp;nil;<br />
<span style="color: #008080">44</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cls-&gt;ivar_layout&nbsp;=&nbsp;&amp;UnsetLayout;<br />
<span style="color: #008080">45</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cls-&gt;ext&nbsp;=&nbsp;nil;<br />
<span style="color: #008080">46</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;allocateExt(cls);<br />
<span style="color: #008080">47</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cls-&gt;ext-&gt;weak_ivar_layout&nbsp;=&nbsp;&amp;UnsetLayout;<br />
<span style="color: #008080">48</span>&nbsp;<br />
<span style="color: #008080">49</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meta-&gt;ivars&nbsp;=&nbsp;nil;<br />
<span style="color: #008080">50</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meta-&gt;methodLists&nbsp;=&nbsp;nil;<br />
<span style="color: #008080">51</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meta-&gt;cache&nbsp;=&nbsp;(Cache)&amp;_objc_empty_cache;<br />
<span style="color: #008080">52</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meta-&gt;protocols&nbsp;=&nbsp;nil;<br />
<span style="color: #008080">53</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meta-&gt;ext&nbsp;=&nbsp;nil;<br />
<span style="color: #008080">54</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<span style="color: #008080">55</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">return</span>&nbsp;cls;<br />
<span style="color: #008080">56</span>&nbsp;}</div>
</div>
<p>&nbsp;<strong><span style="font-family: Times New Roman">2.3.2.3 </span><span style="font-family: 宋体">添加成员变量</span><span style="font-family: Times New Roman"> </span></strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; objc_allocateClassPair方法只创建了一个<span style="color: red; font-size: 10pt"><strong>没有任何成员的类实例</strong></span>,若要添加变量可以调用class_addIvar方法。由于类实例是对象实例操作的导航对象,若往类实例中添加了新变量,则需要修改objc_class对象中的instance_size成员值。可查看runtime.h文件中的class_addIvar方法实现: </p>
<div class="cnblogs_code">
<div><span style="color: #008080">&nbsp;1</span>&nbsp;BOOL&nbsp;class_addIvar(Class&nbsp;cls,&nbsp;<span style="color: #0000ff">const</span>&nbsp;<span style="color: #0000ff">char</span>&nbsp;*name,&nbsp;size_t&nbsp;size,&nbsp;uint8_t&nbsp;alignment,&nbsp;<span style="color: #0000ff">const</span>&nbsp;<span style="color: #0000ff">char</span>&nbsp;*type)<br />
<span style="color: #008080">&nbsp;2</span>&nbsp;{<br />
<span style="color: #008080">&nbsp;3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;old_ivar_list&nbsp;*old&nbsp;=&nbsp;cls-&gt;ivars;<br />
<span style="color: #008080">&nbsp;4</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;oldSize;<br />
<span style="color: #008080">&nbsp;5</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">int</span>&nbsp;newCount;<br />
<span style="color: #008080">&nbsp;6</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;old_ivar&nbsp;*ivar;<br />
<span style="color: #008080">&nbsp;7</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br />
<span style="color: #008080">&nbsp;8</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">&nbsp;创建新的地址空间,并复制原来变量链表中的内容</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;9</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cls-&gt;ivars&nbsp;=&nbsp;(old_ivar_list&nbsp;*)&nbsp;calloc(oldSize+<span style="color: #0000ff">sizeof</span>(old_ivar),&nbsp;<span style="color: #800080">1</span>);<br />
<span style="color: #008080">10</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">if</span>&nbsp;(old)&nbsp;memcpy(cls-&gt;ivars,&nbsp;old,&nbsp;oldSize);<br />
<span style="color: #008080">11</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">if</span>&nbsp;(old&nbsp;&nbsp;&amp;&amp;&nbsp;&nbsp;malloc_size(old))&nbsp;free(old);<br />
<span style="color: #008080">12</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cls-&gt;ivars-&gt;ivar_count&nbsp;=&nbsp;newCount;<br />
<span style="color: #008080">13</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ivar&nbsp;=&nbsp;&amp;cls-&gt;ivars-&gt;ivar_list[newCount-<span style="color: #800080">1</span>];<br />
<span style="color: #008080">14</span>&nbsp;<br />
<span style="color: #008080">15</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">&nbsp;设置新添加变量的内容</span><span style="color: #008000"><br />
</span><span style="color: #008080">16</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ivar-&gt;ivar_name&nbsp;=&nbsp;strdup(name);<br />
<span style="color: #008080">17</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ivar-&gt;ivar_type&nbsp;=&nbsp;strdup(type);<br />
<span style="color: #008080">18</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ivar-&gt;ivar_offset&nbsp;=&nbsp;(<span style="color: #0000ff">int</span>)cls-&gt;instance_size;<br />
<span style="color: #008080">19</span>&nbsp;<br />
<span style="color: #008080">20</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cls-&gt;instance_size&nbsp;+=&nbsp;(<span style="color: #0000ff">long</span>)size;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">&nbsp;加长对象实例的大小</span><span style="color: #008000"><br />
</span><span style="color: #008080">21</span>&nbsp;<span style="color: #008000"></span><br />
<span style="color: #008080">22</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">return</span>&nbsp;result;<br />
<span style="color: #008080">23</span>&nbsp;}</div>
</div>
<p><strong><span style="font-family: Times New Roman">2.3.3 </span><span style="font-family: 宋体">元类实例</span><span style="font-family: Times New Roman"> </span></strong></p>
<p><strong><span style="font-family: Times New Roman">2.3.3.1 </span><span style="font-family: 宋体">内存空间布局</span><span style="font-family: Times New Roman"> </span></strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 元类实例也是objc_class结构体的实例化对象,并且其创建过程也可在objc_allocateClassPair方法中进行,同时同一个类的所有对象拥有同一个元类实例。不同的是该实例是类实例的"导航",其存放类实例的所有信息,当要操作类方法时,就通过元类实例来操作类实例。 </p>
<p><strong><span style="font-family: Times New Roman">2.3.3.2 </span><span style="font-family: 宋体">三实例的关系</span><span style="font-family: Times New Roman"> </span></strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于同一个类中的对象实例、类实例和元类实例之间存在紧密的联系,其中对象实例存在多个,而类实例和元类实例是只存在一个。由定义 21和定义 22可知,objc_object结构体存在isa指针,而objc_class结构体存在isa和superclass指针,三实例就是通过这些指针进行联系的,如图 22所示是三者的关系图。 </p>
<p style="text-align: center"></p>
<div align="center">
<div align="center"><img alt="" src="http://images2015.cnblogs.com/blog/499013/201604/499013-20160424091900179-1711364331.png" /></div>
</div>
<p align="center">&nbsp;<span style="font-size: 9pt">图 23 三实例之间的关系 </span></p>
<p><span style="color: red; font-size: 10pt"><strong>注意: </strong></span></p>
<p style="text-align: justify"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1) root class为基类,一般NSObject为基类,若创建的类不基础任何类,则所创建的类为基类。 </span></p>
<p style="text-align: justify"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2) 所有元类的isa指针都指向root class的元类实例,包括root class meta本身。 </span></p>
<p style="text-align: justify"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3) class meta的superclass指针指向父类的meta,但root class meta的superclass指针则指向root class。 </span></p>
<p style="text-align: justify"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4) root class的superclass指针为空。 </span></p>
<p><span style="font-size: 12pt"><strong><span style="font-family: Times New Roman">2.4 </span><span style="font-family: 宋体">简单示例</span><span style="font-family: Times New Roman"> </span></strong></span></p>
<p><strong><span style="font-family: Times New Roman">2.4.1 </span><span style="font-family: 宋体">动态创建类和对象</span><span style="font-family: Times New Roman"> </span></strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 本例在运行时,动态创建一个类,并添加一个方法;接着创建给类的一个实例对象。在类的方法中输出其对象实例、类实例、元类实例、基元类实例等地址,从而验证图 22所示关系图的正确性。 </p>
<div>
<div class="cnblogs_code">
<div><span style="color: #008080">&nbsp;1</span>&nbsp;<span style="color: #0000ff">void</span>&nbsp;ReportFunction(id&nbsp;self,&nbsp;SEL&nbsp;_cmd)<br />
<span style="color: #008080">&nbsp;2</span>&nbsp;{<br />
<span style="color: #008080">&nbsp;3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">This&nbsp;object&nbsp;is&nbsp;%p.</span><span style="color: #800000">"</span>,&nbsp;self);<br />
<span style="color: #008080">&nbsp;4</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">Class&nbsp;is&nbsp;%@,&nbsp;and&nbsp;super&nbsp;is&nbsp;%@.</span><span style="color: #800000">"</span>,&nbsp;[self&nbsp;<span style="color: #0000ff">class</span>],&nbsp;[self&nbsp;superclass]);<br />
<span style="color: #008080">&nbsp;5</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<span style="color: #008080">&nbsp;6</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class&nbsp;currentClass&nbsp;=&nbsp;[self&nbsp;<span style="color: #0000ff">class</span>];<br />
<span style="color: #008080">&nbsp;7</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">for</span>&nbsp;(<span style="color: #0000ff">int</span>&nbsp;i&nbsp;=&nbsp;<span style="color: #800080">1</span>;&nbsp;i&nbsp;&lt;&nbsp;<span style="color: #800080">5</span>;&nbsp;i++)<br />
<span style="color: #008080">&nbsp;8</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
<span style="color: #008080">&nbsp;9</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">Following&nbsp;the&nbsp;isa&nbsp;pointer&nbsp;%d&nbsp;times&nbsp;gives&nbsp;%p</span><span style="color: #800000">"</span>,&nbsp;i,&nbsp;currentClass);<br />
<span style="color: #008080">10</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;currentClass&nbsp;=&nbsp;object_getClass(currentClass);<br />
<span style="color: #008080">11</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080">12</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<span style="color: #008080">13</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">NSObject's&nbsp;class&nbsp;is&nbsp;%p</span><span style="color: #800000">"</span>,&nbsp;[NSObject&nbsp;<span style="color: #0000ff">class</span>]);<br />
<span style="color: #008080">14</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">NSObject's&nbsp;meta&nbsp;class&nbsp;is&nbsp;%p</span><span style="color: #800000">"</span>,&nbsp;object_getClass([NSObject&nbsp;<span style="color: #0000ff">class</span>]));<br />
<span style="color: #008080">15</span>&nbsp;}<br />
<span style="color: #008080">16</span>&nbsp;-(<span style="color: #0000ff">void</span>)&nbsp;report<br />
<span style="color: #008080">17</span>&nbsp;{<br />
<span style="color: #008080">18</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class&nbsp;newClass&nbsp;=&nbsp;objc_allocateClassPair([NSError&nbsp;<span style="color: #0000ff">class</span>],&nbsp;<span style="color: #800000">"</span><span style="color: #800000">RuntimeErrorSubclass</span><span style="color: #800000">"</span>,&nbsp;<span style="color: #800080">0</span>);<br />
<span style="color: #008080">19</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class_addMethod(newClass,&nbsp;@selector(report),&nbsp;(IMP)ReportFunction,&nbsp;<span style="color: #800000">"</span><span style="color: #800000">v@:</span><span style="color: #800000">"</span>);<span style="color: #008000">//</span><span style="color: #008000">"v@:"用于描述所添加方法的参数类型。v表示方法的返回参数类型,@表示第一个参数的类型,:表示第二个参数的类型。更多类型可参考Objective-C&nbsp;Runtime&nbsp;Programming&nbsp;Guide&nbsp;&gt;&nbsp;Type&nbsp;Encodings.</span><span style="color: #008000"><br />
</span><span style="color: #008080">20</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;objc_registerClassPair(newClass);<br />
<span style="color: #008080">21</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<span style="color: #008080">22</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id&nbsp;instanceOfNewClass&nbsp;=&nbsp;[[newClass&nbsp;alloc]&nbsp;initWithDomain:<span style="color: #800000">@"</span><span style="color: #800000">someDomain</span><span style="color: #800000">"</span>&nbsp;code:<span style="color: #800080">0</span>&nbsp;userInfo:nil];<br />
<span style="color: #008080">23</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[instanceOfNewClass&nbsp;performSelector:@selector(report)];<br />
<span style="color: #008080">24</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[instanceOfNewClass&nbsp;release];<br />
<span style="color: #008080">25</span>&nbsp;}<br />
<span style="color: #008080">26</span>&nbsp;-(<span style="color: #0000ff">void</span>)&nbsp;main<br />
<span style="color: #008080">27</span>&nbsp;{<br />
<span style="color: #008080">28</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[self&nbsp;report];<br />
<span style="color: #008080">29</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">return</span>;<br />
<span style="color: #008080">30</span>&nbsp;}<br />
<span style="color: #008080">31</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">37</span>:<span style="color: #800080">41.173</span>&nbsp;runtimeProject[<span style="color: #800080">882</span>:<span style="color: #800080">81773</span>]&nbsp;This&nbsp;<span style="color: #0000ff">object</span>&nbsp;<span style="color: #0000ff">is</span>&nbsp;<span style="color: #800080">0x7fd5c8c02d30</span>.<br />
<span style="color: #008080">32</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">37</span>:<span style="color: #800080">41.174</span>&nbsp;runtimeProject[<span style="color: #800080">882</span>:<span style="color: #800080">81773</span>]&nbsp;Class&nbsp;<span style="color: #0000ff">is</span>&nbsp;RuntimeErrorSubclass,&nbsp;and&nbsp;super&nbsp;<span style="color: #0000ff">is</span>&nbsp;NSError.<br />
<span style="color: #008080">33</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">37</span>:<span style="color: #800080">41.174</span>&nbsp;runtimeProject[<span style="color: #800080">882</span>:<span style="color: #800080">81773</span>]&nbsp;Following&nbsp;the&nbsp;isa&nbsp;pointer&nbsp;<span style="color: #800080">1</span>&nbsp;times&nbsp;gives&nbsp;<span style="color: #800080">0x7fd5c8c03180</span><br />
<span style="color: #008080">34</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">37</span>:<span style="color: #800080">41.174</span>&nbsp;runtimeProject[<span style="color: #800080">882</span>:<span style="color: #800080">81773</span>]&nbsp;Following&nbsp;the&nbsp;isa&nbsp;pointer&nbsp;<span style="color: #800080">2</span>&nbsp;times&nbsp;gives&nbsp;<span style="color: #800080">0x7fd5c8c048c0</span><br />
<span style="color: #008080">35</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">37</span>:<span style="color: #800080">41.174</span>&nbsp;runtimeProject[<span style="color: #800080">882</span>:<span style="color: #800080">81773</span>]&nbsp;Following&nbsp;the&nbsp;isa&nbsp;pointer&nbsp;<span style="color: #800080">3</span>&nbsp;times&nbsp;gives&nbsp;<span style="color: #800080">0x103ada198</span><br />
<span style="color: #008080">36</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">37</span>:<span style="color: #800080">41.175</span>&nbsp;runtimeProject[<span style="color: #800080">882</span>:<span style="color: #800080">81773</span>]&nbsp;Following&nbsp;the&nbsp;isa&nbsp;pointer&nbsp;<span style="color: #800080">4</span>&nbsp;times&nbsp;gives&nbsp;<span style="color: #800080">0x103ada198</span><br />
<span style="color: #008080">37</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">37</span>:<span style="color: #800080">41.175</span>&nbsp;runtimeProject[<span style="color: #800080">882</span>:<span style="color: #800080">81773</span>]&nbsp;NSObject<span style="color: #800000">'</span><span style="color: #800000">s&nbsp;class&nbsp;is&nbsp;0x103ada170</span><span style="color: #800000"><br />
</span><span style="color: #008080">38</span>&nbsp;<span style="color: #800000"></span><span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">37</span>:<span style="color: #800080">41.175</span>&nbsp;runtimeProject[<span style="color: #800080">882</span>:<span style="color: #800080">81773</span>]&nbsp;NSObject<span style="color: #800000">'</span><span style="color: #800000">s&nbsp;meta&nbsp;class&nbsp;is&nbsp;0x103ada198</span></div>
</div>
</div>
<p><strong><span style="font-family: Times New Roman">2.4.2 </span><span style="font-family: 宋体">类与对象的操作函数</span><span style="font-family: Times New Roman"> </span></strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 本例采用静态方式创建一个类,然后采用动态方式输出该类的信息。 </p>
<div class="cnblogs_code">
<div><span style="color: #008080">&nbsp;&nbsp;1</span>&nbsp;@interface&nbsp;MyClass&nbsp;:&nbsp;NSObject&lt;NSCopying,&nbsp;NSCoding&gt;<br />
<span style="color: #008080">&nbsp;&nbsp;2</span>&nbsp;@property&nbsp;(nonatomic,&nbsp;strong)&nbsp;NSArray&nbsp;*array;<br />
<span style="color: #008080">&nbsp;&nbsp;3</span>&nbsp;@property&nbsp;(nonatomic,&nbsp;copy)&nbsp;NSString&nbsp;*<span style="color: #0000ff">string</span>;<br />
<span style="color: #008080">&nbsp;&nbsp;4</span>&nbsp;<br />
<span style="color: #008080">&nbsp;&nbsp;5</span>&nbsp;-&nbsp;(<span style="color: #0000ff">void</span>)method1;<br />
<span style="color: #008080">&nbsp;&nbsp;6</span>&nbsp;-&nbsp;(<span style="color: #0000ff">void</span>)method2;<br />
<span style="color: #008080">&nbsp;&nbsp;7</span>&nbsp;+&nbsp;(<span style="color: #0000ff">void</span>)classMethod1;<br />
<span style="color: #008080">&nbsp;&nbsp;8</span>&nbsp;@end<br />
<span style="color: #008080">&nbsp;&nbsp;9</span>&nbsp;-(<span style="color: #0000ff">void</span>)&nbsp;main<br />
<span style="color: #008080">&nbsp;10</span>&nbsp;{<br />
<span style="color: #008080">&nbsp;11</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@autoreleasepool&nbsp;{<br />
<span style="color: #008080">&nbsp;12</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyClass&nbsp;*myClass&nbsp;=&nbsp;[[MyClass&nbsp;alloc]&nbsp;init];<br />
<span style="color: #008080">&nbsp;13</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;<span style="color: #0000ff">int</span>&nbsp;outCount&nbsp;=&nbsp;<span style="color: #800080">0</span>;<br />
<span style="color: #008080">&nbsp;14</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class&nbsp;cls&nbsp;=&nbsp;myClass.<span style="color: #0000ff">class</span>;<br />
<span style="color: #008080">&nbsp;15</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">&nbsp;类名</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;16</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">class&nbsp;name:&nbsp;%s</span><span style="color: #800000">"</span>,&nbsp;class_getName(cls));<br />
<span style="color: #008080">&nbsp;17</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">==========================================================</span><span style="color: #800000">"</span>);<br />
<span style="color: #008080">&nbsp;18</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">&nbsp;父类</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;19</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">super&nbsp;class&nbsp;name:&nbsp;%s</span><span style="color: #800000">"</span>,&nbsp;class_getName(class_getSuperclass(cls)));<br />
<span style="color: #008080">&nbsp;20</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">==========================================================</span><span style="color: #800000">"</span>);<br />
<span style="color: #008080">&nbsp;21</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<span style="color: #008080">&nbsp;22</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">&nbsp;是否是元类</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;23</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">MyClass&nbsp;is&nbsp;%@&nbsp;a&nbsp;meta-class</span><span style="color: #800000">"</span>,&nbsp;(class_isMetaClass(cls)&nbsp;?&nbsp;<span style="color: #800000">@""</span>&nbsp;:&nbsp;<span style="color: #800000">@"</span><span style="color: #800000">not</span><span style="color: #800000">"</span>));<br />
<span style="color: #008080">&nbsp;24</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">==========================================================</span><span style="color: #800000">"</span>);<br />
<span style="color: #008080">&nbsp;25</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<span style="color: #008080">&nbsp;26</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class&nbsp;meta_class&nbsp;=&nbsp;objc_getMetaClass(class_getName(cls));<br />
<span style="color: #008080">&nbsp;27</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">%s's&nbsp;meta-class&nbsp;is&nbsp;%s</span><span style="color: #800000">"</span>,&nbsp;class_getName(cls),&nbsp;class_getName(meta_class));<br />
<span style="color: #008080">&nbsp;28</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">==========================================================</span><span style="color: #800000">"</span>);<br />
<span style="color: #008080">&nbsp;29</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<span style="color: #008080">&nbsp;30</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">&nbsp;变量实例大小</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;31</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">instance&nbsp;size:&nbsp;%zu</span><span style="color: #800000">"</span>,&nbsp;class_getInstanceSize(cls));<br />
<span style="color: #008080">&nbsp;32</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">==========================================================</span><span style="color: #800000">"</span>);<br />
<span style="color: #008080">&nbsp;33</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<span style="color: #008080">&nbsp;34</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">&nbsp;成员变量</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;35</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ivar&nbsp;*ivars&nbsp;=&nbsp;class_copyIvarList(cls,&nbsp;&amp;outCount);<br />
<span style="color: #008080">&nbsp;36</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">for</span>&nbsp;(<span style="color: #0000ff">int</span>&nbsp;i&nbsp;=&nbsp;<span style="color: #800080">0</span>;&nbsp;i&nbsp;&lt;&nbsp;outCount;&nbsp;i++)&nbsp;{<br />
<span style="color: #008080">&nbsp;37</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ivar&nbsp;ivar&nbsp;=&nbsp;ivars[i];<br />
<span style="color: #008080">&nbsp;38</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">instance&nbsp;variable's&nbsp;name:&nbsp;%s&nbsp;at&nbsp;index:&nbsp;%d</span><span style="color: #800000">"</span>,&nbsp;ivar_getName(ivar),&nbsp;i);<br />
<span style="color: #008080">&nbsp;39</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080">&nbsp;40</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free(ivars);<br />
<span style="color: #008080">&nbsp;41</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<span style="color: #008080">&nbsp;42</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ivar&nbsp;<span style="color: #0000ff">string</span>&nbsp;=&nbsp;class_getInstanceVariable(cls,&nbsp;<span style="color: #800000">"</span><span style="color: #800000">_string</span><span style="color: #800000">"</span>);<br />
<span style="color: #008080">&nbsp;43</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">if</span>&nbsp;(<span style="color: #0000ff">string</span>&nbsp;!=&nbsp;NULL)&nbsp;{<br />
<span style="color: #008080">&nbsp;44</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">instace&nbsp;variable&nbsp;%s</span><span style="color: #800000">"</span>,&nbsp;ivar_getName(<span style="color: #0000ff">string</span>));<br />
<span style="color: #008080">&nbsp;45</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080">&nbsp;46</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<span style="color: #008080">&nbsp;47</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">==========================================================</span><span style="color: #800000">"</span>);<br />
<span style="color: #008080">&nbsp;48</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">&nbsp;属性操作</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;49</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;objc_property_t&nbsp;*&nbsp;properties&nbsp;=&nbsp;class_copyPropertyList(cls,&nbsp;&amp;outCount);<br />
<span style="color: #008080">&nbsp;50</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">for</span>&nbsp;(<span style="color: #0000ff">int</span>&nbsp;i&nbsp;=&nbsp;<span style="color: #800080">0</span>;&nbsp;i&nbsp;&lt;&nbsp;outCount;&nbsp;i++)&nbsp;{<br />
<span style="color: #008080">&nbsp;51</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;objc_property_t&nbsp;property&nbsp;=&nbsp;properties[i];<br />
<span style="color: #008080">&nbsp;52</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">property's&nbsp;name:&nbsp;%s</span><span style="color: #800000">"</span>,&nbsp;property_getName(property));<br />
<span style="color: #008080">&nbsp;53</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080">&nbsp;54</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<span style="color: #008080">&nbsp;55</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free(properties);<br />
<span style="color: #008080">&nbsp;56</span>&nbsp;<br />
<span style="color: #008080">&nbsp;57</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;objc_property_t&nbsp;array&nbsp;=&nbsp;class_getProperty(cls,&nbsp;<span style="color: #800000">"</span><span style="color: #800000">array</span><span style="color: #800000">"</span>);<br />
<span style="color: #008080">&nbsp;58</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">if</span>&nbsp;(array&nbsp;!=&nbsp;NULL)&nbsp;{<br />
<span style="color: #008080">&nbsp;59</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">property&nbsp;%s</span><span style="color: #800000">"</span>,&nbsp;property_getName(array));<br />
<span style="color: #008080">&nbsp;60</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080">&nbsp;61</span>&nbsp;<br />
<span style="color: #008080">&nbsp;62</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">==========================================================</span><span style="color: #800000">"</span>);<br />
<span style="color: #008080">&nbsp;63</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">&nbsp;方法操作</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;64</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Method&nbsp;*methods&nbsp;=&nbsp;class_copyMethodList(cls,&nbsp;&amp;outCount);<br />
<span style="color: #008080">&nbsp;65</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">for</span>&nbsp;(<span style="color: #0000ff">int</span>&nbsp;i&nbsp;=&nbsp;<span style="color: #800080">0</span>;&nbsp;i&nbsp;&lt;&nbsp;outCount;&nbsp;i++)&nbsp;{<br />
<span style="color: #008080">&nbsp;66</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Method&nbsp;method&nbsp;=&nbsp;methods[i];<br />
<span style="color: #008080">&nbsp;67</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">method's&nbsp;signature:&nbsp;%s</span><span style="color: #800000">"</span>,&nbsp;method_getName(method));<br />
<span style="color: #008080">&nbsp;68</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080">&nbsp;69</span>&nbsp;<br />
<span style="color: #008080">&nbsp;70</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free(methods);<br />
<span style="color: #008080">&nbsp;71</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Method&nbsp;method1&nbsp;=&nbsp;class_getInstanceMethod(cls,&nbsp;@selector(method1));<br />
<span style="color: #008080">&nbsp;72</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">if</span>&nbsp;(method1&nbsp;!=&nbsp;NULL)&nbsp;{<br />
<span style="color: #008080">&nbsp;73</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">method&nbsp;%s</span><span style="color: #800000">"</span>,&nbsp;method_getName(method1));<br />
<span style="color: #008080">&nbsp;74</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080">&nbsp;75</span>&nbsp;<br />
<span style="color: #008080">&nbsp;76</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Method&nbsp;classMethod&nbsp;=&nbsp;class_getClassMethod(cls,&nbsp;@selector(classMethod1));<br />
<span style="color: #008080">&nbsp;77</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">if</span>&nbsp;(classMethod&nbsp;!=&nbsp;NULL)&nbsp;{<br />
<span style="color: #008080">&nbsp;78</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">class&nbsp;method&nbsp;:&nbsp;%s</span><span style="color: #800000">"</span>,&nbsp;method_getName(classMethod));<br />
<span style="color: #008080">&nbsp;79</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080">&nbsp;80</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<span style="color: #008080">&nbsp;81</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">MyClass&nbsp;is%@&nbsp;responsd&nbsp;to&nbsp;selector:&nbsp;method3WithArg1:arg2:</span><span style="color: #800000">"</span>,&nbsp;class_respondsToSelector(cls,&nbsp;@selector(method3WithArg1:arg2:))&nbsp;?&nbsp;<span style="color: #800000">@""</span>&nbsp;:&nbsp;<span style="color: #800000">@"</span><span style="color: #800000">&nbsp;not</span><span style="color: #800000">"</span>);<br />
<span style="color: #008080">&nbsp;82</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IMP&nbsp;imp&nbsp;=&nbsp;class_getMethodImplementation(cls,&nbsp;@selector(method1));<br />
<span style="color: #008080">&nbsp;83</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;imp();<br />
<span style="color: #008080">&nbsp;84</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<span style="color: #008080">&nbsp;85</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">==========================================================</span><span style="color: #800000">"</span>);<br />
<span style="color: #008080">&nbsp;86</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">&nbsp;协议</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;87</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Protocol&nbsp;*&nbsp;__unsafe_unretained&nbsp;*&nbsp;protocols&nbsp;=&nbsp;class_copyProtocolList(cls,&nbsp;&amp;outCount);<br />
<span style="color: #008080">&nbsp;88</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Protocol&nbsp;*&nbsp;protocol;<br />
<span style="color: #008080">&nbsp;89</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">for</span>&nbsp;(<span style="color: #0000ff">int</span>&nbsp;i&nbsp;=&nbsp;<span style="color: #800080">0</span>;&nbsp;i&nbsp;&lt;&nbsp;outCount;&nbsp;i++)&nbsp;{<br />
<span style="color: #008080">&nbsp;90</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;protocol&nbsp;=&nbsp;protocols[i];<br />
<span style="color: #008080">&nbsp;91</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">protocol&nbsp;name:&nbsp;%s</span><span style="color: #800000">"</span>,&nbsp;protocol_getName(protocol));<br />
<span style="color: #008080">&nbsp;92</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080">&nbsp;93</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<span style="color: #008080">&nbsp;94</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">MyClass&nbsp;is%@&nbsp;responsed&nbsp;to&nbsp;protocol&nbsp;%s</span><span style="color: #800000">"</span>,&nbsp;class_conformsToProtocol(cls,&nbsp;protocol)&nbsp;?&nbsp;<span style="color: #800000">@""</span>&nbsp;:&nbsp;<span style="color: #800000">@"</span><span style="color: #800000">&nbsp;not</span><span style="color: #800000">"</span>,&nbsp;protocol_getName(protocol));<br />
<span style="color: #008080">&nbsp;95</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">==========================================================</span><span style="color: #800000">"</span>);<br />
<span style="color: #008080">&nbsp;96</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080">&nbsp;97</span>&nbsp;}<br />
<span style="color: #008080">&nbsp;98</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.403</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;<span style="color: #0000ff">class</span>&nbsp;name:&nbsp;MyClass<br />
<span style="color: #008080">&nbsp;99</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.404</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;==========================================================<br />
<span style="color: #008080">100</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.404</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;super&nbsp;<span style="color: #0000ff">class</span>&nbsp;name:&nbsp;NSObject<br />
<span style="color: #008080">101</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.404</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;==========================================================<br />
<span style="color: #008080">102</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.404</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;MyClass&nbsp;<span style="color: #0000ff">is</span>&nbsp;not&nbsp;a&nbsp;meta-<span style="color: #0000ff">class</span><br />
<span style="color: #008080">103</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.404</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;==========================================================<br />
<span style="color: #008080">104</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.404</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;MyClass<span style="color: #800000">'</span><span style="color: #800000">s&nbsp;meta-class&nbsp;is&nbsp;MyClass</span><span style="color: #800000"><br />
</span><span style="color: #008080">105</span>&nbsp;<span style="color: #800000"></span><span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.405</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;==========================================================<br />
<span style="color: #008080">106</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.405</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;instance&nbsp;size:&nbsp;<span style="color: #800080">24</span><br />
<span style="color: #008080">107</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.405</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;==========================================================<br />
<span style="color: #008080">108</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.405</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;instance&nbsp;variable<span style="color: #800000">'</span><span style="color: #800000">s&nbsp;name:&nbsp;_array&nbsp;at&nbsp;index:&nbsp;0</span><span style="color: #800000"><br />
</span><span style="color: #008080">109</span>&nbsp;<span style="color: #800000"></span><span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.405</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;instance&nbsp;variable<span style="color: #800000">'</span><span style="color: #800000">s&nbsp;name:&nbsp;_string&nbsp;at&nbsp;index:&nbsp;1</span><span style="color: #800000"><br />
</span><span style="color: #008080">110</span>&nbsp;<span style="color: #800000"></span><span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.405</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;instace&nbsp;variable&nbsp;_string<br />
<span style="color: #008080">111</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.405</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;==========================================================<br />
<span style="color: #008080">112</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.406</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;property<span style="color: #800000">'</span><span style="color: #800000">s&nbsp;name:&nbsp;array</span><span style="color: #800000"><br />
</span><span style="color: #008080">113</span>&nbsp;<span style="color: #800000"></span><span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.406</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;property<span style="color: #800000">'</span><span style="color: #800000">s&nbsp;name:&nbsp;string</span><span style="color: #800000"><br />
</span><span style="color: #008080">114</span>&nbsp;<span style="color: #800000"></span><span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.406</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;property&nbsp;array<br />
<span style="color: #008080">115</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.406</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;==========================================================<br />
<span style="color: #008080">116</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.406</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;method<span style="color: #800000">'</span><span style="color: #800000">s&nbsp;signature:&nbsp;method1</span><span style="color: #800000"><br />
</span><span style="color: #008080">117</span>&nbsp;<span style="color: #800000"></span><span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.407</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;method<span style="color: #800000">'</span><span style="color: #800000">s&nbsp;signature:&nbsp;method2</span><span style="color: #800000"><br />
</span><span style="color: #008080">118</span>&nbsp;<span style="color: #800000"></span><span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.407</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;method<span style="color: #800000">'</span><span style="color: #800000">s&nbsp;signature:&nbsp;method3WithArg1:arg2:</span><span style="color: #800000"><br />
</span><span style="color: #008080">119</span>&nbsp;<span style="color: #800000"></span><span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.407</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;method<span style="color: #800000">'</span><span style="color: #800000">s&nbsp;signature:&nbsp;setArray:</span><span style="color: #800000"><br />
</span><span style="color: #008080">120</span>&nbsp;<span style="color: #800000"></span><span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.407</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;method<span style="color: #800000">'</span><span style="color: #800000">s&nbsp;signature:&nbsp;string</span><span style="color: #800000"><br />
</span><span style="color: #008080">121</span>&nbsp;<span style="color: #800000"></span><span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.407</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;method<span style="color: #800000">'</span><span style="color: #800000">s&nbsp;signature:&nbsp;setString:</span><span style="color: #800000"><br />
</span><span style="color: #008080">122</span>&nbsp;<span style="color: #800000"></span><span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.407</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;method<span style="color: #800000">'</span><span style="color: #800000">s&nbsp;signature:&nbsp;array</span><span style="color: #800000"><br />
</span><span style="color: #008080">123</span>&nbsp;<span style="color: #800000"></span><span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.408</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;method&nbsp;method1<br />
<span style="color: #008080">124</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.408</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;<span style="color: #0000ff">class</span>&nbsp;method&nbsp;:&nbsp;classMethod1<br />
<span style="color: #008080">125</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.408</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;MyClass&nbsp;<span style="color: #0000ff">is</span>&nbsp;responsd&nbsp;to&nbsp;selector:&nbsp;method3WithArg1:arg2:<br />
<span style="color: #008080">126</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.408</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;call&nbsp;method&nbsp;method1<br />
<span style="color: #008080">127</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.409</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;==========================================================<br />
<span style="color: #008080">128</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.409</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;protocol&nbsp;name:&nbsp;NSCopying<br />
<span style="color: #008080">129</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.409</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;protocol&nbsp;name:&nbsp;NSCoding<br />
<span style="color: #008080">130</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.409</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;MyClass&nbsp;<span style="color: #0000ff">is</span>&nbsp;responsed&nbsp;to&nbsp;protocol&nbsp;NSCoding<br />
<span style="color: #008080">131</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">22</span>&nbsp;<span style="color: #800080">19</span>:<span style="color: #800080">51</span>:<span style="color: #800080">02.410</span>&nbsp;runtimeProject[<span style="color: #800080">1017</span>:<span style="color: #800080">91880</span>]&nbsp;==========================================================</div>
</div>
<p><span style="font-size: 15pt"><strong><span style="font-family: Times New Roman">3</span><span style="font-family: 宋体">、成员变量与属性</span><span style="font-family: Times New Roman"> </span></strong></span></p>
<p><span style="font-size: 12pt"><strong><span style="font-family: Times New Roman">3.1 </span><span style="font-family: 宋体">数据结构</span><span style="font-family: Times New Roman"> </span></strong></span></p>
<p><span style="font-family: Times New Roman"><strong>3.1.1 Ivar </strong></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Ivar是表示实例变量的类型,其实际是一个指向objc_ivar结构体的指针,其定义如下: </p>
<div>
<table style="background-color: #f2dbdb; border-collapse: collapse" border="0" align="center">
    <colgroup>
    <col style="width: 590px"></colgroup>
    <tbody valign="top">
        <tr>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="color: #aa0d91; font-size: 9pt">typedef<span style="color: black"> <span style="color: #aa0d91">struct<span style="color: black"> objc_ivar *Ivar;</span></span></span></span></p>
            </td>
        </tr>
        <tr>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="color: #aa0d91; font-size: 9pt">struct<span style="color: black"> objc_ivar { </span></span></p>
            <p><span style="color: black; font-size: 9pt"><span style="color: #aa0d91">char<span style="color: black"> *ivar_name OBJC2_UNAVAILABLE; <span style="color: #e36c0a"><strong>// 变量名</strong><span style="color: black"> </span></span></span></span></span></p>
            <p><span style="color: black; font-size: 9pt"><span style="color: #aa0d91">char<span style="color: black"> *ivar_type OBJC2_UNAVAILABLE; <span style="color: #e36c0a"><strong>// 变量类型</strong><span style="color: black"> </span></span></span></span></span></p>
            <p><span style="color: black; font-size: 9pt"><span style="color: #aa0d91">int<span style="color: black"> ivar_offset OBJC2_UNAVAILABLE; <span style="color: #e36c0a"><strong>// 基地址偏移字节</strong><span style="color: black"> </span></span></span></span></span></p>
            <p><span style="color: #643820; font-size: 9pt">#ifdef __LP64__ </span></p>
            <p><span style="color: black; font-size: 9pt"><span style="color: #aa0d91">int<span style="color: black"> space OBJC2_UNAVAILABLE; </span></span></span></p>
            <p><span style="color: #643820; font-size: 9pt">#endif </span></p>
            <p><span style="color: black; font-size: 9pt">} </span></p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; objc_ivar结构体中的ivar_type成员描述了变量的类型,而runtime系统定义了一套标识符来描述Objective-C语言中的每种类型。通过@encode编译器指令,可从Objective-C类型的编译为runtime标识符,即@encode返回这个类型的字符串编码。这些类型可以是诸如int、指针这样的基本类型,也可以是结构体、类等类型。事实上,任何可以作为sizeof()操作参数的类型都可以用于@encode()。所有编码类型可参考在[2]Type Encoding小节。 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;一个数组的类型编码位于方括号中;其中包含数组元素的个数及元素类型。如所示: </p>
<div>
<div class="cnblogs_code">
<div><span style="color: #008080">1</span>&nbsp;<span style="color: #0000ff">float</span>&nbsp;a[]&nbsp;=&nbsp;{<span style="color: #800080">1.0</span>,&nbsp;<span style="color: #800080">2.0</span>,&nbsp;<span style="color: #800080">3.0</span>};<br />
<span style="color: #008080">2</span>&nbsp;NSLog(<span style="color: #800000">@"</span><span style="color: #800000">array&nbsp;encoding&nbsp;type:&nbsp;%s</span><span style="color: #800000">"</span>,&nbsp;@encode(<span style="color: #0000ff">typeof</span>(a)));<br />
<span style="color: #008080">3</span>&nbsp;<span style="color: #800080">2016</span>-<span style="color: #800080">02</span>-<span style="color: #800080">25</span>&nbsp;<span style="color: #800080">20</span>:<span style="color: #800080">00</span>:<span style="color: #800080">28.489</span>&nbsp;runtimeProject[<span style="color: #800080">977</span>:<span style="color: #800080">88513</span>]&nbsp;array&nbsp;encoding&nbsp;type:&nbsp;[3f]</div>
</div>
</div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 另外对于属性而言,还会有一些特殊的类型编码,以表明属性是只读、拷贝、retain等等,详情可以参考[2]Property Type String小节。 </p>
<p><span style="font-family: Times New Roman"><strong>3.1.2 objc_property_t </strong></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; objc_property_t是表示Objective-C声明的属性的类型,及定义了objc_property_attribute_t,为属性的特性(attribute)。如下所示: </p>
<div>
<table style="background-color: #f2dbdb; border-collapse: collapse" border="0" align="center">
    <colgroup>
    <col style="width: 590px"></colgroup>
    <tbody valign="top">
        <tr>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="color: #aa0d91; font-size: 9pt">typedef<span style="color: black"> <span style="color: #aa0d91">struct<span style="color: black"> objc_property *objc_property_t;</span></span></span></span></p>
            </td>
        </tr>
        <tr>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="color: #aa0d91; font-size: 9pt">typedef<span style="color: black"> <span style="color: #aa0d91">struct<span style="color: black"> { </span></span></span></span></p>
            <p><span style="color: black; font-size: 9pt"><span style="color: #aa0d91">const<span style="color: black"> <span style="color: #aa0d91">char<span style="color: black"> *name; <span style="color: #007400">/**&lt; The name of the attribute */<span style="color: black"> </span></span></span></span></span></span></span></p>
            <p><span style="color: black; font-size: 9pt"><span style="color: #aa0d91">const<span style="color: black"> <span style="color: #aa0d91">char<span style="color: black"> *value; <span style="color: #007400">/**&lt; The value of the attribute (usually empty) */<span style="color: black"> </span></span></span></span></span></span></span></p>
            <p><span style="color: black; font-size: 9pt">} objc_property_attribute_t;</span></p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p>&nbsp;<span style="font-size: 15pt"><strong><span style="font-family: Times New Roman">4</span><span style="font-family: 宋体">、方法与消息</span><span style="font-family: Times New Roman"> </span></strong></span></p>
<p><span style="font-size: 12pt"><strong><span style="font-family: Times New Roman">4.1 </span><span style="font-family: 宋体">数据结构</span><span style="font-family: Times New Roman"> </span></strong></span></p>
<p><span style="font-family: Times New Roman"><strong>4.1.1 SEL </strong></span></p>
<p style="text-align: justify"><span style="font-size: 10pt"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1) 定义 </strong></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; SEL又叫选择器,用于标识一个方法。Objective-C在编译时,会依据每一个方法的名字生成一个唯一的整型标识(Int类型的地址),这个标识就是SEL。如下是SEL的定义: </p>
<p style="text-align: justify"><span style="font-size: 9pt">定义 41 SEL结构体定义 </span></p>
<div>
<table style="border-collapse: collapse" border="0" align="center">
    <colgroup>
    <col style="width: 590px"></colgroup>
    <tbody valign="top">
        <tr style="background: #f2dbdb">
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="font-family: Arial; color: #97007e; font-size: 9pt">typedef<span style="color: #323232"> <span style="color: #97007e">struct<span style="color: #323232"> <span style="color: #491187">objc_selector<span style="color: #323232"> *<span style="color: #981b7e">SEL<span style="color: #323232">;</span></span></span></span></span></span></span></span></p>
            </td>
        </tr>
        <tr style="background: #fde9d9">
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="font-size: 9pt">SEL sel1 = @selector(method1); </span></p>
            <p><span style="font-size: 9pt">NSLog(@"sel : %p", sel1);</span>&nbsp;</p>
            </td>
        </tr>
        <tr style="background: #fde9d9">
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="font-size: 9pt">2014-10-30 18:40:07.518 RuntimeTest[52734:466626] sel : 0x100002d72</span>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p><span style="color: red; font-size: 10pt"><strong>注意: </strong></span></p>
<p><span style="font-size: 9pt"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 可以通过sel_registerName函数动态添加一个新的SEL,并且不能将C类型的字符串直接转换为SEL,需要通过@selector()宏定义进行转换。&nbsp;&nbsp;&nbsp;&nbsp; </strong></span></p>
<p style="text-align: justify"><span style="font-size: 10pt"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2)SEL关系 </strong></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SEL在runtime中是唯一的,即只要方法或函数的名字相同,那么生成的SEL标识值就一样。所以在Objective-C同一个类(及类的继承体系)中,不能存在2个同名的方法,即使参数类型不同也不行。相同的方法只能对应一个SEL。这也就导致了Objective-C语言中不存在函数多态,如在某个类中定义以下两个方法,将发生编译错误: </p>
<div>
<table style="background-color: #fde9d9; border-collapse: collapse" border="0" align="center">
    <colgroup>
    <col style="width: 590px"></colgroup>
    <tbody valign="top">
        <tr>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="font-size: 9pt">- (void)setWidth:(int)width; </span></p>
            <p><span style="font-size: 9pt">- (void)setWidth:(double)width;</span>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当然,不同的类可以拥有相同的selector,这个没有问题。不同类的实例对象执行相同的selector时,会在各自的方法列表中去根据selector去寻找自己对应的IMP。 </p>
<p><span style="font-family: Times New Roman"><strong>4.1.2 IMP </strong></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<span style="color: red"><span style="font-size: 10pt"><strong>IMP实际上是一个函数指针,指向函数实现的首地址。<span style="color: #a09916">即IMP是一个函数的通用实现结构体,表示一个函数的实现,</span></strong></span>其定义如下:</span> </p>
<p style="text-align: justify"><span style="font-size: 9pt">定义 42 IMP结构体定义 </span></p>
<div>
<table style="background-color: #f2dbdb; border-collapse: collapse" border="0" align="center">
    <colgroup>
    <col style="width: 590px"></colgroup>
    <tbody valign="top">
        <tr>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="color: #981b7e; font-size: 9pt">id<span style="color: #323232"> (*<span style="color: #491187">IMP<span style="color: #323232">)(<span style="color: #981b7e">id<span style="color: #323232">, <span style="color: #981b7e">SEL<span style="color: #323232">, ...)</span></span></span></span></span></span></span></span></p>
            </td>
        </tr>
        <tr>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="font-size: 9pt">第一个参数:指向self的指针(如果是实例方法,则是类实例的内存地址;如果是类方法,则是指向元类的指针); </span></p>
            <p><span style="font-size: 9pt">第二个参数:方法选择器(selector); </span></p>
            <p><span style="font-size: 9pt">后续参数:为方法的实际参数列表。</span></p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p>&nbsp;<span style="font-family: Times New Roman"><strong>4.1.3 Method </strong></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 函数由两部分组成:函数声明和函数实现。函数声明由SEL结构体表示,而函数实现由IMP结构体表示。在runtime中采用Method结构体来描述类的函数,其定义如下: </p>
<p style="text-align: justify"><span style="font-size: 9pt">定义 43 Method结构体定义 </span></p>
<div>
<table style="background-color: #f2dbdb; border-collapse: collapse" border="0" align="center">
    <colgroup>
    <col style="width: 590px"></colgroup>
    <tbody valign="top">
        <tr>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="color: #aa0d91; font-size: 9pt">typedef<span style="color: black"> <span style="color: #aa0d91">struct<span style="color: black"> objc_method *Method;</span></span></span></span></p>
            </td>
        </tr>
        <tr>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="color: #aa0d91; font-size: 9pt">struct<span style="color: black"> objc_method { </span></span></p>
            <p><span style="color: black; font-size: 9pt"><span style="color: #aa0d91">SEL<span style="color: black"> method_name OBJC2_UNAVAILABLE; </span></span></span></p>
            <p><span style="color: black; font-size: 9pt"><span style="color: #aa0d91">char<span style="color: black"> *method_types OBJC2_UNAVAILABLE; </span></span></span></p>
            <p><span style="color: black; font-size: 9pt"><span style="color: #aa0d91">IMP<span style="color: black"> method_imp OBJC2_UNAVAILABLE; </span></span></span></p>
            <p><span style="color: black; font-size: 9pt">} </span></p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 可以看到该结构体中包含一个SEL和IMP,实际上相当于在SEL和IMP之间作了一个映射。有了SEL,我们便可以找到对应的IMP,从而调用方法的实现代码。 </p>
<p><span style="font-size: 12pt"><strong><span style="font-family: Times New Roman">4.2 </span><span style="font-family: 宋体">消息发送</span><span style="font-family: Times New Roman"> </span></strong></span></p>
<p><strong><span style="font-family: Times New Roman">4.2.1 </span><span style="font-family: 宋体">发送流程</span><span style="font-family: Times New Roman"> </span></strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在Objective-C中,消息直到运行时才会绑定到方法的实现上。如当执行"[receiver message]"语句时,会被转换为"objc_msgSend(receiver, selector)"语句。而objc_msgSend函数在runtime的声明为: </p>
<div>
<table style="background-color: #f2dbdb; border-collapse: collapse" border="0" align="center">
    <colgroup>
    <col style="width: 590px"></colgroup>
    <tbody valign="top">
        <tr>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="font-family: Arial; color: #981b7e; font-size: 9pt">id<span style="color: #323232"> <span style="color: #491187">objc_msgSend<span style="color: #323232">(<span style="color: #981b7e">id<span style="color: #323232"> <span style="color: #491187">self<span style="color: #323232">, <span style="color: #981b7e">SEL<span style="color: #323232"> <span style="color: #491187">op<span style="color: #323232">, ...)</span></span></span></span></span></span></span></span></span></span></span></span></p>
            </td>
        </tr>
        <tr>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="font-size: 9pt">self参数:指向对象实例的地址; </span></p>
            <p><span style="font-size: 9pt">op参数:为方法名的转换标识; </span></p>
            <p><span style="font-size: 9pt">后续参数:方法的参数。</span></p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; objc_msgSend函数通过receiver实例和selector标识符就能找到相应方法的实现(IMP),从而调用对象的方法。这个搜索对象方法实现的过程就是搜索selector标识符的过程,如图 41所示。 </p>
<p style="text-align: justify"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1) 首先,从当前receiver实例中,获取isa指针,并获取objc_class结构体对象。 </span></p>
<p style="text-align: justify"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2) 接着,从objc_class对象的cache methodLists查找是否有selector。 </span></p>
<p style="text-align: justify"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3) 若无,从objc_class对象的methodLists查找是否有selector。 </span></p>
<p style="text-align: justify"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4) 若无,从objc_class对象的super_class指针所指向的父类中,继续查找。 </span></p>
<p style="text-align: justify"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5) 以此类推,直至找到,则调用objc_method结构体的method_imp成员,即调用方法的实现。 </span></p>
<p style="text-align: justify"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6) 最后再找不到,就会进入动态方法解析和消息转发的机制。 </span></p>
<p style="text-align: center"></p>
<div align="center"><img alt="" src="http://images2015.cnblogs.com/blog/499013/201604/499013-20160424100205929-1592812079.png" /></div>
<p align="center">&nbsp;<span style="font-size: 9pt">图 41 Messaging Framework </span></p>
<p><span style="font-size: 12pt"><strong><span style="font-family: Times New Roman">4.3 </span><span style="font-family: 宋体">消息转发</span><span style="font-family: Times New Roman"> </span></strong></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当一个对象能接收一个消息时,就会走正常的方法调用流程。但如果一个对象接收到无法处理的消息时,它会按序调用该对象的如下方法: </p>
<p style="text-align: justify"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1) resolveInstanceMethod 或 resolveClassMethod </span></p>
<p style="text-align: justify"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2) forwardingTargetForSelector </span></p>
<p style="text-align: justify"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3) forwardInvocation </span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 若上述方法中,仍无法处理消息,那么将抛出一个异常错误,如下所示: </p>
<div>
<table style="background-color: #fde9d9; border-collapse: collapse" border="0" align="center">
    <colgroup>
    <col style="width: 590px"></colgroup>
    <tbody valign="top">
        <tr>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="font-size: 9pt">*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MyClass report]: unrecognized selector sent to instance 0x7ff3134a81c0'</span></p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p>&nbsp;</p>
<p style="text-align: center"></p>
<div align="center"><img alt="" src="http://images2015.cnblogs.com/blog/499013/201604/499013-20160424100329554-1082021940.png" /></div>
<p align="center">&nbsp;<span style="font-size: 9pt">图 42 消息的处理流程 </span></p>
<p><strong><span style="font-family: Times New Roman">4.3.1 </span><span style="font-family: 宋体">动态方法解析</span><span style="font-family: Times New Roman"> </span></strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 若对象接收到未知的消息时,首先会调用所属类的类方法+resolveInstanceMethod:(实例方法)或者+resolveClassMethod:(类方法),从两个方法中查找是否存在所接收的消息,若返回YES表示存在,系统会再次向该对象发送消息。 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 可以在上述两方法中调用class_addMethod函数,向某个类动态添加新方法和实现,其声明为: </p>
<div>
<table style="background-color: #f2dbdb; border-collapse: collapse" border="0" align="center">
    <colgroup>
    <col style="width: 590px"></colgroup>
    <tbody valign="top">
        <tr style="height: 24px">
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="font-family: Arial; color: #981b7e; font-size: 9pt">BOOL<span style="color: #323232"> <span style="color: #491187">class_addMethod<span style="color: #323232">(<span style="color: #491187">Class<span style="color: #323232"> <span style="color: #491187">cls<span style="color: #323232">, <span style="color: #981b7e">SEL<span style="color: #323232"> <span style="color: #491187">name<span style="color: #323232">, <span style="color: #97007e">IMP<span style="color: #323232"> <span style="color: #491187">imp<span style="color: #323232">, <span style="color: #97007e">const<span style="color: #323232"> <span style="color: #981b7e">char<span style="color: #323232"> *<span style="color: #491187">types<span style="color: #323232">)</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
            </td>
        </tr>
        <tr style="height: 24px">
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="font-size: 9pt">cls参数:为添加到某类。 </span></p>
            <p><span style="font-size: 9pt">name参数:响应消息的名字,即name=@selector(methodName)。 </span></p>
            <p><span style="font-size: 9pt">imp参数:为方法的实现地址,即函数的地址。被添加方法至少要有两个参数,参数类型为id和SEL。 </span></p>
            <p><span style="font-size: 9pt">types参数:是一个字符串数组,描述所添加的方法的返回值类型、参数列表的数值类型,</span></p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p><span style="color: red; font-size: 10pt"><strong>注意: </strong></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-size: 9pt">当resolveInstanceMethod或resolveClassMethod方法返回YES后,系统会再次发送消息,若此时仍无法响应消息,将抛出异常错误。 </span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如下是重载某类的resolveInstanceMethod方法,类实现动态添加方法,也可以参考2.4.1动态创建类和对象例子。 </p>
<div class="cnblogs_code">
<div><span style="color: #008080">&nbsp;1</span>&nbsp;<span style="color: #0000ff">void</span>&nbsp;dynamicMethodIMP(id&nbsp;self,&nbsp;SEL&nbsp;_cmd)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">被添加的方法<br />
</span><span style="color: #008080">&nbsp;2</span>&nbsp;<span style="color: #008000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;implementation&nbsp;....</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;3</span>&nbsp;<span style="color: #008000"></span>}<br />
<span style="color: #008080">&nbsp;4</span>&nbsp;@implementation&nbsp;MyClass<br />
<span style="color: #008080">&nbsp;5</span>&nbsp;+&nbsp;(BOOL)resolveInstanceMethod:(SEL)aSEL<br />
<span style="color: #008080">&nbsp;6</span>&nbsp;{<br />
<span style="color: #008080">&nbsp;7</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">if</span>&nbsp;(aSEL&nbsp;==&nbsp;@selector(resolveThisMethodDynamically))&nbsp;{<br />
<span style="color: #008080">&nbsp;8</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class_addMethod([self&nbsp;<span style="color: #0000ff">class</span>],&nbsp;aSEL,&nbsp;(IMP)&nbsp;dynamicMethodIMP,&nbsp;<span style="color: #800000">"</span><span style="color: #800000">v@:</span><span style="color: #800000">"</span>);<br />
<span style="color: #008080">&nbsp;9</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">return</span>&nbsp;YES;&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">表示找到,让其重新调用。</span><span style="color: #008000"><br />
</span><span style="color: #008080">10</span>&nbsp;<span style="color: #008000"></span>&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080">11</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff">return</span>&nbsp;[super&nbsp;resolveInstanceMethod:aSEL];&nbsp;&nbsp;<span style="color: #008000">//</span><span style="color: #008000">若找不到,则往父类中查找是否存在aSEL消息的响应方法</span><span style="color: #008000"><br />
</span><span style="color: #008080">12</span>&nbsp;<span style="color: #008000"></span>}<br />
<span style="color: #008080">13</span>&nbsp;@end</div>
</div>
<p><strong><span style="font-family: Times New Roman">4.3.2 </span><span style="font-family: 宋体">备用接收者</span><span style="font-family: Times New Roman"> </span></strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果上述resolveInstanceMethod或resolveClassMethod方法返回NO后,则Runtime会继续调以下方法: </p>
<div>
<table style="background-color: #f2dbdb; border-collapse: collapse" border="0" align="center">
    <colgroup>
    <col style="width: 590px"></colgroup>
    <tbody valign="top">
        <tr>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="font-size: 9pt">- (id)forwardingTargetForSelector:(SEL)aSelector</span>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果一个对象实现了这个方法,并返回一个非nil的结果,则这个返回的对象会作为消息的新接收者,且消息会被分发到这个对象。当然这个对象不能是self自身,否则就是出现无限循环。当然,如果我们没有指定相应的对象来处理aSelector,则应该调用父类的实现来返回结果。 </p>
<p><strong><span style="font-family: Times New Roman">4.3.3 </span><span style="font-family: 宋体">完整消息转发</span><span style="font-family: Times New Roman"> </span></strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果上述forwardingTargetForSelector返回nil,则Runtime会继续调以下方法: </p>
<div>
<table style="background-color: #f2dbdb; border-collapse: collapse" border="0" align="center">
    <colgroup>
    <col style="width: 590px"></colgroup>
    <tbody valign="top">
        <tr>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="font-size: 9pt">- (void)forwardInvocation:(NSInvocation *)anInvocation</span>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p>forwardInvocation:方法的实现有两个任务: </p>
<p style="text-align: justify"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1) 定位可以响应封装在anInvocation中的消息的对象。这个对象不需要能处理所有未知消息。 </span></p>
<p style="text-align: justify"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2) 使用anInvocation作为参数,将消息发送到选中的对象。anInvocation将会保留调用结果,运行时系统会提取这一结果并将其发送到消息的原始发送者。 </span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 还有一个很重要的问题,我们必须重写以下方法: </p>
<div>
<table style="background-color: #f2dbdb; border-collapse: collapse" border="0" align="center">
    <colgroup>
    <col style="width: 590px"></colgroup>
    <tbody valign="top">
        <tr>
            <td style="padding-left: 7px; padding-right: 7px">
            <p><span style="font-size: 9pt">- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector</span></p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 消息转发机制使用从这个方法中获取的信息来创建NSInvocation对象。因此我们必须重写这个方法,为给定的selector提供一个合适的方法签名。 </p>
<p><span style="color: red; font-size: 10pt"><strong>备注: </strong></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-size: 9pt">个人感觉,没必要到第三步来处理未知的消息,这个太麻烦了,能处理的操作直接在上述两步完成即可。 </span></p>
<p><span style="font-size: 15pt"><strong><span style="font-family: Times New Roman">5</span><span style="font-family: 宋体">、参考文献</span><span style="font-family: Times New Roman"> </span></strong></span></p>
<p style="text-align: justify"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [1].Objective-C Runtime Reference </span></p>
<p style="text-align: justify"><span style="font-size: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [2].Objective-C Runtime Programming Guide </span></p>
<p style="text-align: justify">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [3].<a href="http://opensource.apple.com/tarballs/objc4/"><span style="font-size: 10pt">Objective-C 源码</span></a><span style="font-size: 10pt"> </span></p>
<p style="text-align: justify">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [4].<a href="http://southpeak.github.io/blog/archives/"><span style="font-size: 10pt">《Objective-C Runtime 运行时》序列文章 </span></a></p>
<p style="text-align: justify">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [5].<a href="http://justsee.iteye.com/blog/2163777"><span style="font-size: 10pt">《Objective-C Runtime》博客</span></a><span style="font-size: 10pt"> </span></p>
<p style="text-align: justify">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [6].<a href="http://blog.csdn.net/windyitian/article/details/19810875"><span style="font-size: 10pt">详解Objective-C的meta-class</span></a><span style="font-size: 10pt"> </span></p>
<p style="text-align: justify">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [7].<a href="http://chun.tips/blog/2014/11/05/bao-gen-wen-di-objective%5Bnil%5Dc-runtime(1)%5Bnil%5D-self-and-super/"><span style="font-size: 10pt">刨根问底Objective-C Runtime</span></a><span style="font-size: 10pt"> </span></p>

原创粉丝点击