检查对象是不是为类类型

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 &lt;objc/runtime.h&gt;

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,这就是为什么存在 idNSObject 协议的原因。查看NSProxy,它是它自己的根类developer.apple.com/library/mac/#documentation/Cocoa/Reference/… @Joe 我不知道 NSProxy,很高兴知道!但实际上我使用 NSObject 只是为了使示例更容易,我将使用它来验证我的核心数据中的类,所以每个类都必须是 NSManagedObject 类型,然后规则将适用。但是感谢您指出!【参考方案2】:

更新:ios 8+ 或 OS X 10.10+ 中,您可以这样做:

object_isClass(obj)

(您需要#import &lt;objc/runtime.h&gt;。)

【讨论】:

我认为您必须为此导入某种花哨的标头,嗯? @user102008 还有,有没有参考链接? @GradyPlayer:它是&lt;objc/runtime.h&gt;,就像此页面上的所有其他答案一样 我知道你在叹气,但我们只是想让你的答案更好。 使用@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

zepto源码--几个判断函数--学习笔记

PLSQL - 检查对象表中是不是存在对象 - 类型没有映射

Python:检查对象是不是不是“数组类型”

检查 Swift 对象是不是是给定元类型的实例

如何检查对象是不是是某种类型的数组?