iOS中运行时的几种基本用法记录

  

  

这不是一遍介绍关于运行时实现细节的文章,而是怎么利用objective - c提供的运行时API进行开发的文章!

  objective - c

拥有相当多的动态特性,这些特性在运行程序时候发挥作用。

  

Objctive-C运行时是个运行时的库,由C和汇编实现。通过运行时封装的C结构体和函数可以在程序运行时创建,检查和修改类以及对象及其方法,甚至可以替换或交换方法的实现。

  

<强>下面记录一下关于运行时的一些基本用法

  

  

在OOP术语中,消息传递是指一种在对象之间发送和接收消息的通信模式。
  

  

在objective - c中,消息传递用于在调用类和类实例的方法,即接收者接收需要执行的消息。

  

使用案例

     //通过类名获取类   类catClass=objc_getClass(“猫”);//注意类实际上也是对象,所以同样能够接受消息,向类发送alloc消息   猫*猫=objc_msgSend (catClass @ selector (alloc));//发送init消息给猫实例猫   猫=objc_msgSend(猫,@ selector (init));//发送吃的消息给猫,即调用吃的方法   objc_msgSend(猫,@ selector(吃));//汇总消息传递过程   objc_msgSend (objc_msgSend (objc_msgSend (objc_getClass(“猫”),sel_registerName (“alloc”)), sel_registerName (“init”)), sel_registerName("吃"));      

<强> 2)方法交换方法纵酒

  objective - c

提供了一下API用于动态替换类方法或者实例方法的实现:

  
      <李> class_replaceMethod替换类方法的定义李   <李> method_exchangeImplementations交换两个方法的实现(具体使用案例如下)   <李> methodsetimplementation设置一个方法的实现李   
  

class_replaceMethod试图替换一个不存在的方法时候,会调用class_addMethod为该类增加一个新方法

  

使用案例

     //Cat.m      +(空白)负载{   方法eatMethod=class_getInstanceMethod(自我,@ selector(吃));   方法shirtMethod=class_getInstanceMethod(自我,@ selector(衬衫));      method_exchangeImplementations (eatMethod shirtMethod);   }      - (void)吃{   NSLog(@“猫吃....”);   }      - (void)衬衫{   NSLog(@“猫衬衫....”);   }      

<强> 3)动态加载方法

  

当调用一个未实现的方法,或者说发送未知的消息给接收者时候,消息的接受者会调用resolveInstanceMethod

  

使用案例

     //Cat.m//一个objective - C方法仅仅是一个C函数,至少需要两个arguments-self和_cmd。   空运行(id自我、选取_cmd NSNumber *数量){   NSLog(@ % @“跑”,编号);   }//收到运行:消息时候,为该类添加一个方法实现   + (BOOL) resolveInstanceMethod: (SEL)选取{   如果(sel==NSSelectorFromString (@“:”)) {   class_addMethod(自我,@ selector(运行:)、运行“v@: @”);   返回YES;   }   返回(超级resolveInstanceMethod:选取);   }//另外针对类方法的为resolveClassMethod      

<强> 4)消息转发
  

     //第一步,消息接收者没有找到对应的方法时候,会先调用此方法,可在此方法实现中动态添加新的方法//返回是的表示相应选择器的实现已经被找的到,或者添加新方法到了类中,否则返回不   + (BOOL) resolveInstanceMethod: (SEL)选取{   返回YES;   }//第二步,如果第一步的返回没有或者直接返回了是的而没有添加方法,该方法被调用//在这个方法中,我们可以指定一个可以返回一个可以响应该方法的对象,注意如果返回自己就会死循环   - (id) forwardingTargetForSelector (SEL): aSelector {   返回nil;   }//第三步,如果forwardingTargetForSelector:返回了零,则该方法会被调用,系统会询问我们要一个合法的“类型编码(类型编码)”//若返回零,则不会进入下一步,而是无法处理消息   ——(NSMethodSignature *) methodSignatureForSelector (SEL): aSelector {   返回(NSMethodSignature signatureWithObjCTypes:“v@:“);   }//当实现了此方法后,-doesNotRecognizeSelector:将不会被调用//在这里进行消息转发   - (void) forwardInvocation: (NSInvocation *) anInvocation {//在这里可以改变方法选择器   [anInvocation setSelector: @ selector(未知)];//改变方法选择器后,需要指定消息的接收者   [anInvocation invokeWithTarget:自我);   }      - (void)未知的{   NSLog(@“可知方法.......”);   }//如果没有实现消息转发forwardInvocation则调用此方法   - (void) doesNotRecognizeSelector: (SEL) aSelector {   NSLog(@“未解决的方法:% @ NSStringFromSelector (aSelector));   }

iOS中运行时的几种基本用法记录