检查对象是不是为类类型
Posted
技术标签:
【中文标题】检查对象是不是为类类型【英文标题】:Check if object is Class type检查对象是否为类类型 【发布时间】:2011-09-26 01:07:32 【问题描述】:我有一个接收 Class
对象的 NSArray
的方法,我需要检查它们是否都是使用下面的代码生成的 Class
类型:
NSMutableArray *arr = [[NSMutableArray alloc] init];
[arr addObject:[NSObject class]];
[arr addObject:[NSValue class]];
[arr addObject:[NSNumber class]];
[arr addObject:[NSPredicate class]];
[arr addObject:@"not a class object"];
问题是Class
不是objective-c类,是struc,所以不能随便用
for (int i; i<[arr count]; i++)
Class obj = [arr objectAtIndex:i];
if([obj isKindOfClass: [Class class]])
//do sth
所以,我需要检查obj
变量是否是Class
类型,我想它会直接在C
中,但我该怎么做呢?
如果答案还提供了一种方法来检查数组中的项目是否为NSObject
,那将是一个加分项,就像示例代码中的项目一样,NSPredicate
也将是true
的@ 987654334@查看
【问题讨论】:
你说Class
不是obj-C类,所以这个问题有点混乱。数组包含什么,您想将它与什么进行比较?
+1 答案不明显的好问题。
您能否详细说明您打算如何处理类对象数组?您的实际问题有一个答案(打电话给@bbum!),但它可能不如根据您的计划讨论使用它们的最佳方式实际。
***.com/questions/355312/… 的可能重复项
【参考方案1】:
要确定“对象”是类还是实例,您需要在两阶段过程中检查它是否是meta class。首先调用object_getClass
,然后使用class_isMetaClass
检查它是否是一个元类。你需要#import <objc/runtime.h>
。
NSObject *object = [[NSObject alloc] init];
Class class = [NSObject class];
BOOL yup = class_isMetaClass(object_getClass(class));
BOOL nope = class_isMetaClass(object_getClass(object));
Class
和 *id
具有相同的结构布局 (Class isa
),因此可以作为对象并且都可以接收消息,因此很难确定哪个是哪个。这似乎是我能够获得一致结果的唯一方法。
编辑:
这是您的原始支票示例:
NSMutableArray *arr = [[NSMutableArray alloc] init];
[arr addObject:[NSObject class]];
[arr addObject:[NSValue class]];
[arr addObject:[NSNumber class]];
[arr addObject:[NSPredicate class]];
[arr addObject:@"not a class object"];
for (int i; i<[arr count]; i++)
id obj = [arr objectAtIndex:i];
if(class_isMetaClass(object_getClass(obj)))
//do sth
NSLog(@"Class: %@", obj);
else
NSLog(@"Instance: %@", obj);
[arr release];
还有输出:
类:NSObject 类:NSValue 类:NSNumber 类:NSPredicate 实例:不是类对象
【讨论】:
很好的解释!我还可以检查对象是否继承自NSObject
,例如,使用[object_getClass(obj) isSubclassOfClass:[NSObject class]]
。 tks!
@Felipe Sabina 我会坚持使用 class_isMetaClass,因为并非每个对象都保证是 NSObject,这就是为什么存在 id
和 NSObject
协议的原因。查看NSProxy
,它是它自己的根类developer.apple.com/library/mac/#documentation/Cocoa/Reference/…
@Joe 我不知道 NSProxy,很高兴知道!但实际上我使用 NSObject 只是为了使示例更容易,我将使用它来验证我的核心数据中的类,所以每个类都必须是 NSManagedObject 类型,然后规则将适用。但是感谢您指出!【参考方案2】:
更新:在 ios 8+ 或 OS X 10.10+ 中,您可以这样做:
object_isClass(obj)
(您需要#import <objc/runtime.h>
。)
【讨论】:
我认为您必须为此导入某种花哨的标头,嗯? @user102008 还有,有没有参考链接? @GradyPlayer:它是<objc/runtime.h>
,就像此页面上的所有其他答案一样
我知道你在叹气,但我们只是想让你的答案更好。
使用@import ObjectiveC;
... 如果你很性感。【参考方案3】:
乔的回答很好。在大多数情况下,一个简单的替代方法是检查对象是否返回自身以响应class
。
if ([obj class] == obj) …
这是因为NSObject
元类覆盖class
并返回类对象(本身)——参见NSObject Class Reference。这不需要运行时标头,但假定对象是 NSObject
的子类,并且不会覆盖 -class
或 +class
并做一些不寻常的事情。
使用问题中的输入,结果与乔的相同:
NSMutableArray *arr = [[NSMutableArray alloc] init];
[arr addObject:[NSObject class]];
[arr addObject:[NSValue class]];
[arr addObject:[NSNumber class]];
[arr addObject:[NSPredicate class]];
[arr addObject:@"not a class object"];
for (id<NSObject> obj in arr)
if ([obj class] == obj)
NSLog(@"Class: %@", obj);
else
NSLog(@"Instance: %@", obj);
类:NSObject 类:NSValue 类:NSNumber 类:NSPredicate 实例:不是类对象
【讨论】:
这实际上是一个很好的捕获,并且如果您只能检查NSObject
的子类,则更具可读性【参考方案4】:
如果您需要验证数组中的对象是否为Class
对象,那么您可以验证它是否响应类方法。
for ( id obj in arr )
if (([obj respondsToSelector:@selector(isSubclassOfClass:)])
&& (obj == [NSObject class]) )
NSLog(@"%@", obj);
一旦您通过验证它是否响应isSubclassOfClass:
来知道它是一个Class
对象,那么您可以检查与[NSObject class]
的直接相等性。
【讨论】:
如果没有 '&& (obj == [NSObject class])' 检查它会给出所有类。 respondsToSelector: 如何/为什么在课堂上工作?类是否实现了 NSObject protocol? @Eiko 类对象可以执行根类中定义的任何方法,只要它们不与类方法冲突。 @Eiko:根类是指继承层次结构中的根类。它通常是 NSObject,但也可以创建新的根类。 @user102008 这实际上是我的问题 - 是类的根类? @Eiko 我说的是NSObject
。我找不到提及它的确切开发人员文档,但您可以查看此 link
来稍微解释一下。【参考方案5】:
这里没问题,你是怎么做的:
if([NSStringFromClass([obj class]) isEqualToString:@"Class"])
NSLog(@"It is type of Class");
编辑
或者你可以让你的类符合一个协议: 并检查您从数组中获取的 obj 是否符合此协议,如下所示:
if([obj conformsToProtocol:@protocol(MyClassProtocol)])
编辑
或者你可以检查你从数组中得到的是否是 NSObject 兼容的
if ([object conformsToProtocol:@protocol(NSObject)])
// Do something
【讨论】:
我希望进行类似于isKindOfClass:
方法的检查。你看,如果obj
是[NSObject class]
的结果,那么NSStringFromClass([obj class])
将产生字符串“NSObject”
你试过了吗?我在接收 UIView 类型的对象时使用它一次,我正在检查它是否是我的自定义 UIView (MyCustomUIView) 并且它有效。
顺便说一句,您可以使用协议。使您的类符合协议,然后检查您是否从数组中获得的对象。符合这个协议。这样你就会得到你想要的。检查答案编辑
请检查我的第二个编辑我认为这是你正在寻找的东西
我还需要将它与基础框架中的类一起使用......所以我必须为这些类创建协议和类别,尽管这是一个很好的 hack,但这将是一个巨大的麻烦. tks ;)以上是关于检查对象是不是为类类型的主要内容,如果未能解决你的问题,请参考以下文章
无法将类型为“System .__ ComObject”的COM对象强制转换为类类型AgentInfo