没有合适的资源?快使用搜索试试~ 我知道了~
objective-c运行时编程指南
需积分: 9 3 下载量 96 浏览量
2017-12-08
16:08:25
上传
评论
收藏 71KB DOCX 举报
温馨提示
试读
18页
objective-c运行时编程指南,
资源推荐
资源详情
资源评论
OC 运行时编程指南
导言
本文主要内容包括
1、概述
2、参考
3、运行时系统的版本和平台
4、和运行时系统的交互
5、消息
6、动态方法解析
7、消息转发
8、类型编码
9、属性声明
1 概述
Objective-C 语言将决定尽可能 的从编译 和链接时 推迟到运 行时。只 要有可能 ,
Objective-C 总是使用动态的方式来解决问题。这意味着 Objective-C 语言不仅需要一个
编译器,同时也需要一个运行时系统来执行编译好的代码。这里的运行时系统扮演的角色
类似于 Objective-C 语言的操作系统,Objective-C 基于该系统来工作。
本文章将具体介绍 NSObject 类以及 Objective-C 程序是如何与运行时系统交互的。
特别地,本文章还给出来怎样在运行时动态地加载新类和将消息转发给其它对象的范例,
同时也给出了怎样在程序运行时获取对象信息的方法。
通常,如果仅仅写一个 Cocoa 程序,程序员不需要知道和理解 Objective-C 运行时
系统的底层细节,但这篇文章仍然值得推荐阅读,以了解 Objective-C 运行时系统的原理,
并能更好的利用 Objective-C 的优点。
2、参考
《Objecve-C 2.0 运行时系统参考库》描述了 Objecve-C 运行库的数据结构和函数接口。程
序可以通过这些接口来和 Objecve-C 运行时系统交互。例如,您可以增加一个类或者方法,
或者获得所有类的定义列表等。
《Objecve-C 2.0 程序设计语言》介绍了 Objecve-C 语言本身。
《Objecve-C 版本说明》给出了在最近版本的 Mac OS X 系统中关于 Objecve-C 运行时系统
的一些改动。
3、运行时系统的版本和平台
在不同的平台上 Objective-C 运行时系统的版本也不相同
3.1、早期版本和现在版本
Objecve-C 运行时系统有两个已知版本:早期版本和现行版本。
现行版本主要是 Objecve-C 2.0 及与其相关的新特性。
早期版本的编程接口见《Objecve-C 1 运行时系统参考库》;
现行版本的编程接口见《Objecve-C 2.0 运行时系统参考库》。
在现行版本中,最显著的新特性就是实例变量是“健壮(non-fragile )的”:
1)在早期版本中,如果您改变类中实例变量的布局,您必须重新编译该类的所有子类。
2)在现行版本中,如果您改变类中实例变量的布局,您无需重新编译该类的任何子类。
此外,现行版本支持声明 property 的 synthesis 属性(参考《Objective-C 2.0 程序设
计语言》的“属性”一节)。
3.2、平台
iPhone 程序和 Mac OS X 10.5 及以后的系统中的 64 位程序使用的都是 Objective-C 运
行时系统的现行版本。
其它情况(Mac OS X 系统中的 32 位程序)使用的是早期版本。
4、和运行时系统进行交互
Objective-C 程序有三种途径和运行时系统交互:
1.通过 objective-c 源代码。
2.通过 Foundation 框架中类 NSObject 的方法。
3.通过直接调用运行时系统的函数。
4.1、通过 objective-c 源代码
大部分情况下,运行时系统在后台自动运行,您只需编写和编译 Objective-C 源代码。
当您编译 Objective-C 类和方法时,编译器为实现语言动态特性将自动创建一些数据
结构和函数。这些数据结构包含类定义和协议类定义中的信息,如在《 Objective-C 2.0
程序设计语言》中“定义类”和“协议类”一节所讨论的类的对象和协议类的对象,方法选标,
实例变量模板,以及其它来自于源代码的信息。运行时系统的主要功能就是根据源代码中
的表达式发送消息,如“消息”一节所述。
4.2、通过类 NSObject 的方法
Cocoa 程序中绝大部分类都是 NSObject 类的子类,所以大部分都继承了 NSObject 类的
方法,因而继承了 NSObject 的行为。(NSProxy 类是个例外;更多细节参考“消息转发”
一节。)然而,某些情况下,NSObject 类仅仅定义了完成某件事情的模板,而没有提供
所有需要的代码。
例如,NSObject 类定义了 description 方法,返回该类内容的字符串表示。这主要是用
来调试程序——GDB 中的 print-object 方法就是直接打印出该方法返回的字符串。
NSObject 类中该方法的实现并不知道子类中的内容,所以它只是返回类的名字和对象的
地址。NSObject 的子类可以重新实现该方法以提供更多的信息。例如,NSArray 类改写
了该方法来返回 NSArray 类包含的每个对象的内容。
某些 NSObject 的方法只是简单地从运行时系统中获得信息,从而允许对象进行一定程度
的自我检查。例如,
class 返回对象的类;
isKindOfClass:和 isMemberOfClass:检查对象是否在指定的类继承体系中;
respondsToSelector:检查对象能否响应指定的消息;
conformsToProtocol:检查对象是否实现了指定协议类的方法;
methodForSelector:返回指定方法实现的地址。
4.3、通过运行时系统的函数
运行时系统是一个有公开接口的动态库,由一些数据结构和函数的集合组成,这些数据结
构和函数的声明头文件在/usr/include/objc 中。这些函数支持用纯 C 的函数来实现
Objective-C 同样的功能。还有一些函数构成了 NSObject 类方法的基础。这些函数使得
访问运行时系统接口和提供开发工具成为可能。尽管大部分情况下它们在 Objective-C 程
序不是必须的,但是有时候对于 Objecitve-C 程序来说某些函数是非常有用的。
这些函数的文档参见《Objective-C 2.0 运行时系统参考库》。
5、消息
本章节描述了代码的消息表达式如何转换为对 objc_msgSend 函数的调用,如何通
过名字来指定一个方法,以及如何使用 objc_msgSend 函数。以及在需要的情况下避开
动态绑定。
5.1、获得方法地址
避免动态绑定的唯一办法就是取得方法的地址,并且直接像函数调用一样调用它。当
一个方法会被连续调用很多次,而且您希望节省每次调用方法都要发送消息的开销时,使
用方法地址来调用方法就显得很有效。
利用 NSObject 类中的 methodForSelector:方法,您可以获得一个指向方法实现的
指针,并可以使用该指针直接调用方法实现。methodForSelector:返回的指针和赋值的
变量类型必须完全一致,包括方法的参数类型和返回值类型都在类型识别的考虑范围中。
下面的例子展示了怎么使用指针来调用 setFilled:的方法实现:
void (*setter)(id, SEL, BOOL);
int i;
setter = (void (*)(id, SEL, BOOL))[target methodForSelector:@selector(setFilled:)];
for ( i = 0; i < 1000, i++ )
setter(targetList[i], @selector(setFilled:), YES);
方法指针的第一个参数是接收消息的对象(self),第二个参数是方法选标(_cmd)。这
两个参数在方法中是隐藏参数,但使用函数的形式来调用方法时必须显示的给出。
使用 methodForSelector:来避免动态绑定将减少大部分消息的开销,但是这只有在指定
的消息被重复发送很多次时才有意义,例如上面的 for 循环。
注意:methodForSelector:是 Cocoa 运行时系统的提供的功能,而不是 Objective-C
语言本身的功能。
5.2、objc_msgSend 函数
在 Objective-C 中,消息是直到运行的时候才和方法实现绑定的。编译器会把一个消
息表达式:
[receiver message]
转换成一个对消息函数 objc_msgSend 的调用。该函数有两个主要参数:消息接收
者和消息对应的方法名字——也就是方法选标:
objc_msgSend(receiver, selector)
同时接收消息中的任意数目的参数:
objc_msgSend(receiver, selector, arg1, arg2, ...)
该消息函数做了动态绑定所需要的一切:
1)它首先找到选标所对应的方法实现。因为不同的类对同一方法可能会有不同的实现,
所以找到的方法实现依赖于消息接收者的类型。
2)然后将消息接收者对象(指向消息接收者对象的指针)以及方法中指定的参数传给找
到的方法实现。
3)最后,将方法实现的返回值作为该函数的返回值返回。
注意:编译器将自动插入调用该消息函数的代码。您无须在代码中显示调用该消息函数。
消息机制的关键在于编译器为类和对象生成的结构。每个类的结构中至少包括两个基本元
素:
1)指向父类的指针。
2 ) 类 的 方 法 表 。 方 法 表 将 方 法 选 标 和 该 类 的 方 法 实 现 的 地 址 关 联 起 来 。 例 如 ,
setOrigin::的方法选标和 setOrigin::的方法实现的地址关联,display 的方法选标和
display 的方法实现的地址关联,等等。
当新的对象被创建时,其内存同时被分配,实例变量也同时被初始化。对象的第一个
实例变量是一个指向该对象的类结构的指针,叫做 isa。通过该指针,对象可以访问它对
应的类以及相应的父类。
注意:尽管严格来说这并不是 Obective-C 语言的一部分,但是在 Objective-C 运行时系
统中对象需要有 isa 指针。对象和结构体 struct objc_object(在 objc/objc.h 中定义)
剩余17页未读,继续阅读
资源评论
sxh741
- 粉丝: 0
- 资源: 3
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功