• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Objective-C中的反射和反射工厂

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

 本文为原创,欢迎转载和收藏,转载请标明原文地址


 

  程序中可能会出现大量的if-else或者switch-case来选择一系列类中的某个类进行操作,利用反射(Reflection)就可以避免这些重复判断工作。

  反射在Java中封装了类来实现,在Objective-C里面要自己来实现,好在不是很难。

  我们的目的是通过传入一个类名字符串,把字符串类名动态转化成类,并对类进行实例化和调用方法等操作。

 

  OC的NSRuntime中提供了将Class name转化为Class的方法"NSClassFromString()"

 

NSClassFromString //方法原型
Class NSClassFromString (
   NSString *aClassName
);

 

   因此,我们就可以这样使用来动态获得一个类:

NSString * aClassName = @"SunnyClass";
Class class = NSClassFromString(aClassName);

 

  这样我们就能实例化这个类了:

id instance = [[class alloc] init];

 

  如果需要使用方法,最好用reponseToSelector:来检测一下

if([instance reponseToSelector:@selector(aMethod)])
{
    [instance aMethod];
}

 

  这样就完成了反射调用的过程。

  下面就是将反射利用到工厂模式里。

 

  定义一个Fruit,和三种继承自Fruit的水果

@interface Fruit : NSObject
- (void)show;
@end

@interface Apple : Fruit 
@end

@interface Banana : Fruit 
@end

@interface Pear : Fruit 
@end

 

  实现部分,简单的show方法来打印

@implementation Fruit
- (void)show
{
    NSLog(@"I'm a fruit");
}
@end

@implementation Apple
- (void)show
{
    NSLog(@"I'm an apple");
}
@end

@implementation Banana
- (void)show
{
    NSLog(@"I'm a banana");
}
@end

@implementation Pear
- (void)show
{
    NSLog(@"I'm a pear");
}
@end

 

  如果使用传统的if-else分支判断的话,情况就会变得非常恶心,如果想再增加一个Orange类的话,不仅需要增加Orange类的代码,工厂的代码也要新增加else-if分支:

- (Fruit *)createFruitWithName:(NSString *)fruitName
{
    Fruit * theFruit;
    if ([fruitName isEqualToString:@"Apple"]) 
    {
        theFruit = [[[Apple alloc] init] autorelease];
    }
    else if ([fruitName isEqualToString:@"Banana"])
    {
        theFruit = [[[Banana alloc] init] autorelease];
    }
    else if ([fruitName isEqualToString:@"Pear"])
    {
        theFruit = [[[Pear alloc] init] autorelease];
    }
    return theFruit;
}

 

  但如果使用反射工厂的模式,情况就变得简单了许多,扩展性也会变得更好(反射输入的类名最好能来自于一个文件,这个文件规定了哪些字符串是可以作为参数传入的,这里就不考虑了)

@implementation FruitFactroy

- (Fruit *)createFruitWithName:(NSString *)fruitName
{
    //通过string得到类的结构体
    Class class = NSClassFromString(fruitName);
    
    //通过转化的class得到实例对象
    Fruit * theFruit = [(Fruit *)[[class alloc] init] autorelease];
    
    //调用对象方法
    if ([theFruit respondsToSelector:@selector(show)]) 
    {
        [theFruit show];
    }
    
    //返回对象
    return theFruit;
}
@end

 

  工厂方法的调用

    FruitFactroy * factroy = [[[FruitFactroy alloc] init] autorelease];
    Fruit * apple = [factroy createFruitWithName:@"Apple"];
    Fruit * banana = [factroy createFruitWithName:@"Banana"];
    Fruit * pear = [factroy createFruitWithName:@"Pear"];

 

 

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
IEC104公约解析c#使用通过104公约同步时间发布时间:2022-07-13
下一篇:
C++模板类继承的一个小技巧发布时间:2022-07-13
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap