Objective-c中的posing

来源:互联网 发布:mastercam新手编程 编辑:程序博客网 时间:2024/04/30 23:17

谈到这个posing,真是有些惭愧,还没了解这个是怎么回事,就已经被苹果给抹去了。

尽管如此,还是整理了一些文章,以供参考。


===================================================================

Posing,顾名思义,意思是“冒充”,它跟categories类似,但本质上不一样,Posing存在的目的在于子类可以冒充父类,使得后续的代码无需把父类修改为子类,就可以很方便的让父类表现成子类的行为,从而实现非常方便的冒充,这在一般的语言中是难以想象的。
       它允许你扩展一个class,并且全面的冒充这个super class,比如:你有一个扩展NSArray的NSArrayChild对象,如果你让NSArrayChild冒充NSArray,则你程序代码所在的NSArray都会自动替换为NSArrayChild。注意,这里不是指代码替换,而是NSArray所在地方的行为都跟NSArrayChild一样了。
       例子:
1,定义父类:

Fraction.h:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #import <Foundation/NSObject.h>  
  2.   
  3. @interface Fraction : NSObject{  
  4.    int numerator;  
  5.    int denominator;  
  6. }  
  7. -(id)initWithNumeration:(int)a:denominator:(int) b;  
  8. -(void) print;  
  9. @end  

Fraction.m:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #import <stdio.h>  
  2. #import "Fraction.h"  
  3.   
  4. @implementation Fraction  
  5. -(id)initWithNumeration:(int)a:denominator:(int) b {         
  6.     self = [super init];  
  7.     if(self) {  
  8.        numerator   = a;  
  9.        denominator = b;  
  10.     }  
  11.   
  12.     return self;  
  13. }  
  14.   
  15. -(void) print {  
  16.    printf("Fraction: %i/%i", numerator, denominator);  
  17. }  
  18.   
  19. @end  

2,定义子类:


FractionChild.h:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #import "Fraction.h"  
  2. @interface FractionChild : Fraction   
  3. -(void) print;  
  4. @end  

FractionChild.m:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #import <stdio.h>  
  2.   
  3. #import "FractionChild.h"  
  4.   
  5. @implementation FractionChild  
  6. -(void) print {  
  7.    printf("FractionChild: %i/%i", numerator, denominator);  
  8. }  
  9.   
  10. @end  

3, 开始用FractionChild 冒充Fraction
main.m:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #import <stdio.h>  
  2. #import "Fraction.h"  
  3. #import "FractionChild.h"  
  4.   
  5. int main(int agrc, const char * agrv[]) {  
  6.      Fraction *frac = [[Fraction alloc]initWithNumeration:3:denominator:4];  
  7.      [frac print]; //此时输出:Fraction: 3/4  
  8.   
  9.   
  10.      //make FractionChild posing as Fracition,注意:poseAsClass这个方法是NSObject的一个内置方法,用于子类posing父类。  
  11.   
  12.      [FracitonChild poseAsClass [Fraction class]];  
  13.   
  14.   
  15.      Fraction *frac2 = [[Fraction alloc]initWithNumeration:3:denominator:4];  
  16.      [frac2 print]; //此时输出:FractionChild: 3/4,此时的Fration表现行为便被FractionChild冒充了  
  17.   
  18.      [frac release];  
  19.      [frac2 release];  
  20. }  
===========================================================================================================

postAsClass,32位系统中,据说还可以用;但是64位系统或者10.6.5更高的版本都不能使用了。它的作用就是使用FractionPost中的方法替代Fraction中的方法!比如,Fraction中的print方法:-(void) print {?? printf("%i/%i", numerator, denominator);}而在FractionPost中,-(void) print{?? printf("posting:%i/%i", numerator, denominator);} 这样对于Fraction对象的实例就会调用FractionPost中的方法了。当然,前提条件是FractionPost是Fraction的子类。 @interface FractionPost : Fraction { }下面要说的是,既然postAsClass不能使用了,我们用什么方法来继续使用这种功能呢? method_exchangeImplementations(originalMethod, replaceMethod); 这个运行时函数会帮助我们解决这个函数。要使用这个函数,首先导入头文件#import <objc/runtime.h> 完整的用法是:Method originalMethod = class_getInstanceMethod([Fraction class], @selector(print));Method replaceMethod = class_getInstanceMethod([FractionPost class], @selector(print));?method_exchangeImplementations(originalMethod, replaceMethod);首先获取你要替代的方法,这样做本人认为安全性也提高了,假如使用postAsClass,这样所有子类重写了的方法都会被替代。当然,安全性的提高,代价就是功能的削弱。 我相信有一定基础的人都能看懂吧,本人也还在学习基础中。更多相关Method的方法请参考官方library。

0 0
原创粉丝点击