2015-04-03 264 views
3

这是相当先进的东西。我将一些运行时代码作为一个侧面项目搞乱了。我试图解决的问题是这样的:如果我有一个id类型的对象,并且该对象可以是一个字符串,一个类或一个协议,我该如何判断它是什么?iOS:如何判断类型id的对象是类还是协议

例如,这里是一些代码,我搞乱:

[objArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 
    if ([obj isKindOfClass:[NSString class]]) { 
     // Do something with the string ... 
    } else if (... obj is a Protocol ...) { 
     // Do something with the protocol ... 
    } else if (... obj is a Class ...) { 
     // Do something with the class ... 
    } else { 
     // It's something we are not interested in! 
    } 
}]; 

到现在为止我已经没有问题,存储为的NSString,阵列中的类和协议实例的分类和其他的一切都是精细。我需要检测它们的原因很简单,就是我无法控制进入该代码的内容。所以我需要确定循环处理的obj在做什么之前。

我一直在尝试各种运行时功能和东西,但到目前为止没有运气,如果确定什么对象是。

任何人都试过类似的东西?

+0

协议发现被定义为因此,它们实际上可以存储在NSArrays和一个类型NSObject的的喜欢。我已经很成功地做到了这一点。很显然,我正在做的事情是一个非常动态的东西,而且它通常只是Objective C代码的一部分。 – drekka 2015-04-03 13:35:22

回答

2

因为议定书子类NSObject的你可以检测到它以同样的方式对其他任何类。有趣的是,协议类没有公共接口。

类型的对象ID可以是一个类或一个类的一个实例,因此,如果它是一类第一我将测试,和如果失败,这是为此使用字符串比较一个类的实例和确定类名称。为协议比较@“协议”

例 -

// assign the object to inspect 
id obj = //... 
NSString *className; 
// test for Class type first 
if (object_isClass(obj)) { 
// it's a Class... inspect further... 
className = NSStringFromClass(obj); 
if ([className isEqualToString:@"Protocol"]) { /* Protocol Class */ } 
} 
else { 
// must be an instance - get the class name 
className = NSStringFromClass([obj class]); 

// test for instance of Protocol class 
if ([className isEqualToString:@"Protocol"]) { /* Protocol instance */ } 

// continue testing for any other classes here... 

} 

NSStringFromClass在Foundation Functions Reference

+0

谢谢。这几乎是我要去的地方。 – drekka 2015-04-04 11:38:47

2

我现在可能已经找到了解决方案。

要测试一个ID为A类:

NSLog(@"isClass %s", object_isClass(obj) ? "yes":"no"); 

要测试如果ID是一个协议:

NSLog(@"isProtocol %s", object_getClass(obj) == objc_getClass("Protocol") ? "yes":"NO"); 

这些似乎工作,但我认为有可能是一个更好的办法做协议检查。

相关问题