objective20运行时系统编程指南_第1页
objective20运行时系统编程指南_第2页
objective20运行时系统编程指南_第3页
objective20运行时系统编程指南_第4页
objective20运行时系统编程指南_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Objective-C2.0Objective-C语言将决定尽可能的从编译和时推运行时。只要有可能,Objective-C总是使用动态Objective-C语言不仅需要一个编译器,同时也需要一个运行时系统来执行“消息 ——GDBprint-object方法就是直接打印出该方法返回的字符串。NSObject类中该方法的实现并不知道子类中的内容,所以它只是返回类的名字和对象的地址。NSObject的子类可以重新实现某些NSObject的方法只是简单地从运行时系统中获得信息,从而允许对象进行一定程度的自我检查。运行时系统是一个有公开接口的动态库,由一些数据结构和函数的集合组成,这些数据结构和函数的有一些函数构成了NSObject类方法的基础。这些函数使得运行时系统接口和提供开发工具成为可数是非常有用的。这些函数的文档参见Objective-C2.0运行时系统参考库。本章描述了代码的消息表达式如何转换为对objc_msgSend函数的调用,如何通过名字来指定一个方法,以及如何使用objc_msgSend函数。objcmsgSend函数避免动态绑定的唯一办法就是取得方法的地址,并且直接象函数调用一样调用它。当一个方被连续调利用NSObject类中的methodForSelector:方法,您可以获得一个指向方法实现的指针,并可以下面的例子展示了怎么使用指针来调用setFilled:voidvoid(*setter)(id,SEL,BOOL);inti;setter=(void(*)(id,SEL,BOOL))[targetforfor(i=0;i<1000,i++使用methodForSelector:来避免动态绑定将减少大部分消息的开销,但是这只有在指定的消息被重复发送很多次时才有意义,例如上面的for循环。注意,methodForSelector:Cocoa运行时系统的提供的功能,而不是Objective-C语言本身的功 法选标和setOrigin::的方法实现的地址关联,disy的方法选标和disy的 注意:注意:Obective-CObjective-Cisa指针。对象和结构体structobjc_object(在objc/objc.h中定义)必须“一致”。然而,您很少需要创建您自己的根对象,因为从NSObject或者 继承的对象都自动包括isa变量3-13-1旦找到了方法选标,objc_msgSend则以消息接收者对象为参数调用,调用该选标对应的方法实现。源代码中,而是在代码编译时是插入方法的实现中的。尽管这些参数没有被显示,但在源代码中仍然可以它们(就象可以消息接收者对象的实例变量一样)。在方法中可以通过self来消息接收者对象,通过选标_cmd来方法本身。在下面的例子中,_cmd指的是strange方法,self指的收到strange消息的对象。--{idtarget=getTheReceiver();SELmethod=getTheMethod();if(target==self||method==_cmd)returnnil;return[target}@dynamic@dynamic您可以通过实现resolveInstanceMethod:resolveClassMethod:来动态地实现给定选标Objective-C方法可以认为是至少有两个参数——self和_cmd——的CvoidvoiddynamicMethodIMP(idself,SEL_cmd)//implementation}您可以通过resolveInstanceMethod:将它作为类方法resolveThisMethodDynamically+{if(aSEL=={class_addMethod([selfclass],aSEL,(IMP)dynamicMethodIMP,"v@:");returnYES;}return[super}通常消息转发(见“消息转发”)和动态方法解析是互不相干的。在进入消息转发机制之前,您的方式扩展了您的程序,而您无需自己来定义或者实现。您提供了框架,而其它的程序员提供了实信息请参考Foundation框架中关于NSBundle类的文档。关于Mach-O文件的有关信息请参考MacOSXABIMach-O文件格式参考库。关于消息转发的作用,您可以考虑如下情景:假设,您需要设计一个能够响应negotiate消息的对象,并且能够包括其它类型的对象对消息的响应。通过在negotiate方法的实现中将negotiate消息在不同的继承体系中响应negotiate消息。的将negotiate消息转发给其他类的对象,就好像从其它类那儿“借”来的现一样。如下所示:--{if([someOtherObjectrespondsTo:@selector(negotiate)])return[someOtherObjectnegotiate];return}然而,实际上,这个集合会随着运行件的发生,新方法或者新类的定义而变化。forwardInvocation:fowardInvocation:个对象都从NSObject类中继承了forwardInvocatin:NSObject只是简单地调用了doesNotRecognizeSelector:。通过实现您自己的forwardInvocation:消息可以通过invokeWithTarget:{if([someOtherObjectrespondsToSelector:[anInvocationselector]])[super}forwardInvocation:如果您希望您的对象将negotiate消息转发给其它对象,您的对象不能有negotiate消息转发的信息,参考Foundation框架参考库中NSInvocation5-1看起来同时继承自Diplomat和自己的父类。发给消息接收对象的管理细节,保证消息参数的传输等等。但是消息类没有进一步的对象的同时也存在着其它类型的消息对象。例如,假设您有个对象需要操作大量的数据——它可能需要创建一个复杂的或者需要从磁盘上读一个文件的内容。创建一个这样的对象是很费时的,您可能希望能推在这种情况下,你可以为该对象创建一个轻量的对象。该对象可以有一些自己的功能,例如响应数据查询消息,但是它主要的功能是代表某个对象,当时间到来时,将消息转发给被代表的对象。当对象的forwardInvocation:方法收到需要转发给被代表的对象的消息时,对象会保证所代表的对象已经存在,否则就创建它。所有发到被代表的对象的消息都要经过对象,对程序来说,对象尽管消息转发很“象”继承,但它不是继承。例如在NSObject类中,方法respondsToSelector:询问它能否响应negotiate消息,返回值是NO,尽管该对象能够接收和响应negotiate。(5-1。--{if([superrespondsToSelector:aSelector])returnYES;else/*Here,testwhethertheaSelectormessage*beforwardedtoanotherobjectandwhetherthatobjectcanrespondtoit.ReturnYESifitcan.}return}除了respondsToSelector:和isKindOfClass:外,instancesRespondToSelector:方法也必须重新实现。如果您使用的是协议类,需要重新实现的还有conformsToProtocol:方法。mtodintreoSeetor--{NSMethodSignature*signature=[supermethodSignatureForSelector:selector];if(!signature){signature=[surrogate}}return}本节中涉及的方法在Foundation框架参考库中的NSObjectinvokeWithTarget:的具体信息,请参考Foundation框架参考库中NSInvocation在一起。这些编码在别的上下文环境中同样有用,所以您可以直接使用@encode@encode(Csizof()char*buf1=@encode(int**);charchar*buf1=@encode(int**);char*buf2=@encode(structkey);char*buf3=些编码是您写编时候不会使用的,也有一些不是@encode()产生的,但是在您写编的时候是会6-1Objective-CcislqlongCunsignedIunsignedSunsignedLunsignedQunsignedlongfdBC++标准的boolC99标准的v*字符串(char@对象(无论是静态指定的还是通过id的#类:[arraynumbit?Objective-C不支持longdouble@encode(longdouble)double一样,返一个12个浮点数(floats)指针的数组可以表示如下:typedeftypedefstruct{idintanInt;}} @encode()NSObject@encode()的结果中直接得到,但是运行时系统会使用它们来表示协议类中方法的修饰符,这些编码如表6-2所示。6-2Objective-CrnNoORVtypedeftypedefstructobjc_property @interfaceLender:{float}@propertyfloatalone;ididLenderClass=objc_getClass("Lender");unsignedintoutCount;您还可以通过property_getName函数class_getProperty和protocol_getProperty则在类或者协议类中返回具有给定名字 objc_property_tprotocol_getProperty(Protocol*proto,constchar*name,BOOLisRequiredProperty,BOOLisInstanceProperty)ididLenderClass=objc_getClass("Lender");unsignedintoutCount,i;objc_property_t*properties=class_copyPropertyList(LenderClass,&outCount);for(i=0;i<outCount;i++){objc_property_tproperty=}property_getAttributes返回的字符串以字母T开始,接着是@encode如果属性有readonly修饰,则字符串中含有R如果属性有copy或者retain修饰,则字符串分别含有C或者&字符串以V然后是属性的名字结束。范例请参考“属性特征的描述范例”一节。enumenumFooManChu{FOO,MAN,CHUstructYorkshireTeaStruct{intpot;charlady;};typedefstructYorkshireTeaStructYorkshireTeaStructType;unionMoneyUnion{floatalone;doubledown;};@propertychar @propertyfloat@pr

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论