没有合适的资源?快使用搜索试试~ 我知道了~
首页Objective-C 2.0 运行时系统编程指南
Objective-C 2.0 运行时系统编程指南

Objective-C语言将决定尽可能的从编译和链接时推迟到运行时。只要有可能,Objective-C总是使用动态的方式来解决问题。这意味着Objective-C语言不仅需要一个编译器,同时也需要一个运行时系统来执行编译好的代码。这儿的运行时系统扮演的角色类似于Objective-C语言的操作系统,Objective-C基于该系统来工作。本文档将具体介绍NSObject类以及Objective-C程序是如何和运行时系统交互的。特别地,本文档还给出来怎样在运行时动态地加
资源详情
资源评论
资源推荐

Objective-C 2.0 运行时系统编程指南
概述
本部分包括如下内容:
本文档的组织结构
参考
Objective-C 语言将决定尽可能的从编译和链接时推迟到运行时。只要有可能,Objective-C 总是使用动态
的方式来解决问题。这意味着 Objective-C 语言不仅需要一个编译器,同时也需要一个运行时系统来执行
编译好的代码。这儿的运行时系统扮演的角色类似于 Objective-C 语言的操作系统,Objective-C 基于该系
统来工作。
本文档将具体介绍
NSObject 类以及 Objective-C 程序是如何和运行时系统交互的。特别地,本文档还给
出来怎样在运行时动态地加载新类和将消息转发给其它对象的范例,同时也给出了怎样在程序运行时获取
对象信息的方法。
通常,如果是仅仅写一个 Cocoa 程序,您不需要知道和理解 Objective-C 运行时系统的底层细节,但这篇
文档仍然值得推荐您阅读一下,以了解 Objective-C 运行时系统的原理,并能更好的利用 Objective-C 的优
点。
本文档的组织结构
本文档包括如下章节:
“运行时系统的版本和平台”
和运行时系统的交互”
“消息”
“动态方法解析”
“消息转发”
“类型编码”
“属性声明”
参考
Objective-C 2.0
运行时系统参考库
描述了Objective-C运行库的数据结构和函数接口。您的程序可以通过这
些接口来和Objective-C运行时系统交互。例如,您可以增加一个类或者方法,或者获得所有类的定义列表
等。
Objective-C 2.0
程序设计语言
介绍了Objective-C语言本身。
Objective-C
版本说明
给出了在最近版本的Mac OS X系统中关于Objecitive-C运行时系统的一些改动。
运行时系统的版本和平台
在不同的平台上 Objective-C 运行时系统的版本也不相同。
原文地址:http://www.apple.com.cn/developer/Documentation/index.html
整理:http://www.wikinese.com/forum/

本部分包含如下内容:
早期版本和现行版本
平台
早期版本和现行版本
Objective-C运行时系统有两个已知版本:早期版本和现行版本。现行版本主要是Objective-C 2.0 及与其相
关的新特性。早期版本的编程接口见Objective-C 1
运行时系统参考库
;现行版本的编程接口见Objective-C
2.0
运行时系统参考库。
在现行版本中,最显著的新特性就是实例变量是"健壮“(non-fragile)的:
在早期版本中,如果您改变类中实例变量的布局,您必须重新编译该类的所有子类。
在现行版本中,如果您改变类中实例变量的布局,您无需重新编译该类的任何子类。
此外,现行版本支持声明property的synthesis属性(参考Objective-C 2.0
程序设计语言
的属性一节)。
平台
iPhone 程序和 Mac OS X v10.5 及以后的系统中的 64 位程序使用的都是 Objective-C 运行时系统的现行版
本。
其它情况(Mac OS X 系统中的 32 位程序)使用的是早期版本。
和运行时系统的交互
Objective-C 程序有三种途径和运行时系统交互:通过 Objective-C 源代码;通过 Foundation 框架中类
NSObject 的方法;通过直接调用运行时系统的函数。
本部分包含如下内容:
通过Objective-C源代码
通过类NSObject的方法
通过运行时系统的函数
通过Objective-C源代码
大部分情况下,运行时系统在后台自动运行,您只需编写和编译 Objective-C 源代码。
当您编译Objective-C类和方法时,编译器为实现语言动态特性将自动创建一些数据结构和函数。这些数据
结构包含类定义和协议类定义中的信息,如在Objective-C 2.0
程序设计语言
中定义类和协议类一节所讨论
的类的对象和协议类的对象,方法选标,实例变量模板,以及其它来自于源代码的信息。运行时系统的主
要功能就是根据源代码中的表达式发送消息,如"消息
”一节所述。
通过类NSObject的方法
Cocoa程序中绝大部分类都是NSObject类的子类,所以大部分都继承了NSObject类的方法,因而继承
了
NSObject的行为。(NSProxy类是个例外;更多细节参考““消息转发”一节。)然而,某些情况下,
NSObject类仅仅定义了完成某件事情的模板,而没有提供所有需要的代码。
原文地址:http://www.apple.com.cn/developer/Documentation/index.html
整理:http://www.wikinese.com/forum/

例如,NSObject 类定义了 description 方法,返回该类内容的字符串表示。这主要是用来调试程序
——GDB 中的
print-object 方法就是直接打印出该方法返回的字符串。NSObject 类中该方法的
实现并不知道子类中的内容,所以它只是返回类的名字和对象的地址。
NSObject 的子类可以重新实现
该方法以提供更多的信息。例如,
NSArray 类改写了该方法来返回 NSArray 类包含的每个对象的内容。
某些
NSObject 的方法只是简单地从运行时系统中获得信息,从而允许对象进行一定程度的自我检查。
例如,
class 返回对象的类;isKindOfClass:和 isMemberOfClass:则检查对象是否在指定的
类继承体系中;
respondsToSelector:检查对象能否响应指定的消息;conformsToProtocol:
检查对象是否实现了指定协议类的方法;methodForSelector:则返回指定方法实现的地址。
通过运行时系统的函数
运行时系统是一个有公开接口的动态库,由一些数据结构和函数的集合组成,这些数据结构和函数的声明
头文件在
/usr/include/objc 中。这些函数支持用纯 C 的函数来实现和 Objective-C 同样的功能。还
有一些函数构成了
NSObject 类方法的基础。这些函数使得访问运行时系统接口和提供开发工具成为可
能。尽管大部分情况下它们在 Objective-C 程序不是必须的,但是有时候对于 Objecitve-C 程序来说某些函
数是非常有用的。 这些函数的文档参见 Objective-C 2.0
运行时系统参考库
。
消息
本章描述了代码的消息表达式如何转换为对 objc_msgSend 函数的调用,如何通过名字来指定一个方
法,以及如何使用
objc_msgSend 函数。
本部分包含如下内容:
获得方法地址
objc_msgSend函数
使用隐藏的参数
获得方法地址
避免动态绑定的唯一办法就是取得方法的地址,并且直接象函数调用一样调用它。当一个方法会被连续调
用很多次,而且您希望节省每次调用方法都要发送消息的开销时,使用方法地址来调用方法就显得很有效。
利用
NSObject 类中的 methodForSelector:方法,您可以获得一个指向方法实现的指针,并可以
使用该指针直接调用方法实现。
methodForSelector:返回的指针和赋值的变量类型必须完全一致,
包括方法的参数类型和返回值类型都在类型识别的考虑范围中。
下面的例子展示了怎么使用指针来调用
setFilled:的方法实现:
void (*setter)(id, SEL, BOOL);
int i;
setter = (void (*)(id, SEL, BOOL))[target
methodForSelector:@selector(setFilled:)];
原文地址:http://www.apple.com.cn/developer/Documentation/index.html
整理:http://www.wikinese.com/forum/

for ( i = 0; i < 1000, i++ )
setter(targetList[i], @selector(setFilled:), YES);
方法指针的第一个参数是接收消息的对象(self),第二个参数是方法选标(_cmd)。这两个参数在方
法中是隐藏参数,但使用函数的形式来调用方法时必须显示的给出。
使用 methodForSelector:来避免动态绑定将减少大部分消息的开销,但是这只有在指定的消息被重
复发送很多次时才有意义,例如上面的
for 循环。
注意,
methodForSelector:是 Cocoa 运行时系统的提供的功能,而不是 Objective-C 语言本身的功
能。
objc_msgSend函数
在 Objective-C 中,消息是直到运行的时候才和方法实现绑定的。编译器会把一个消息表达式,
[receiver message]
转换成一个对消息函数 objc_msgSend 的调用。该函数有两个主要参数:消息接收者和消息对应的方法
名字——也就是方法选标:
objc_msgSend(receiver, selector)
同时接收消息中的任意数目的参数:
objc_msgSend(receiver, selector, arg1, arg2, ...)
该消息函数做了动态绑定所需要的一切:
它首先找到选标所对应的方法实现。因为不同的类对同一方法可能会有不同的实现,所以找到的
方法实现依赖于消息接收者的类型。
然后将消息接收者对象(指向消息接收者对象的指针)以及方法中指定的参数传给找到的方法实
现。
最后,将方法实现的返回值作为该函数的返回值返回。
注意:编译器将自动插入调用该消息函数的代码。您无须在代码中显示调用该消息函数。
消息机制的关键在于编译器为类和对象生成的结构。每个类的结构中至少包括两个基本元素:
指向父类的指针。
类的方法表。方法表将方法选标和该类的方法实现的地址关联起来。例如,setOrigin::的方
法选标和
setOrigin::的方法实现的地址关联,display 的方法选标和 display 的
方法实现的地址关联,等等。
当新的对象被创建时,其内存同时被分配,实例变量也同时被初始化。对象的第一个实例变量是一个指向
该对象的类结构的指针,叫做
isa。通过该指针,对象可以访问它对应的类以及相应的父类。
注意:尽管严格来说这并不是 Obective-C 语言的一部分,但是在 Objective-C 运行时系统中对象需要有
isa 指针。对象和结构体 struct objc_object(在 objc/objc.h 中定义)必须“一致”。然而,
您很少需要创建您自己的根对象,因为从 NSObject 或者 NSProxy 继承的对象都自动包括 isa 变量。
原文地址:http://www.apple.com.cn/developer/Documentation/index.html
整理:http://www.wikinese.com/forum/
剩余17页未读,继续阅读













安全验证
文档复制为VIP权益,开通VIP直接复制

评论8