C语言 检查对象是否为类类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6536244/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 09:03:10  来源:igfitidea点击:

Check if object is Class type

objective-cctype-conversion

提问by Felipe Sabino

I have a method that receives a NSArrayof Classobjects and I need to check if they all are Classtype generated with the code bellow:

我有一个接收的方法NSArrayClass对象,我需要检查,如果他们都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"];

The problem is that Classis not an objective-c class, it is a struc, so I can not use just

问题是这Class不是一个objective-c类,它是一个结构,所以我不能只使用

    for (int i; i<[arr count]; i++) {
        Class obj = [arr objectAtIndex:i];

        if([obj isKindOfClass: [Class class]]) {
            //do sth
        }
    }

So, I need to I check if the objvariable is a Classtype, I suppose it will be in Cdirectly, but how can I do that?

所以,我需要检查obj变量是否是一种Class类型,我想它会C直接存在,但是我该怎么做呢?

It will be a plus if the answer also provide a way to check if the item in the array is a NSObject, as the items in the example code, the NSPredicatewould also be truefor the NSObjectcheck

如果答案还提供了一种检查数组中的项目是否为 a 的方法NSObject,就像示例代码中的项目一样,NSPredicate这也将true用于NSObject检查

回答by Joe

To determine if an "object" is a class or an instance you need to check if it is a meta classin a two stage process. First call object_getClassthen check if it is a meta class using class_isMetaClass. You will need to #import <objc/runtime.h>.

要确定“对象”是类还是实例,您需要在两阶段过程中检查它是否是元类。首先调用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));

Both Classand *idhave the same struct layout (Class isa), therefore can pose as objects and can both receive messages making it hard to determine which is which. This seems to be the only way I was able to get consistent results.

二者Class*id具有相同的结构布局(Class isa),因此可以构成为对象,并且可以既接收消息使得难以确定哪个是哪个。这似乎是我能够获得一致结果的唯一方法。

EDIT:

编辑:

Here is your original example with the check:

这是您的原始支票示例:

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];

And the output:

和输出:

Class: NSObject
Class: NSValue
Class: NSNumber
Class: NSPredicate
Instance: not a class object

类:NSObject
类:NSValue
类:NSNumber
类:NSPredicate
实例:不是类对象

回答by user102008

Update:In iOS 8+ or OS X 10.10+, you can just do:

更新:在 iOS 8+ 或 OS X 10.10+ 中,你可以这样做:

object_isClass(obj)

(You will need to #import <objc/runtime.h>.)

(你将需要#import <objc/runtime.h>。)

回答by Douglas Hill

Joe's answer is good. A simple alternative that works in most situations is to check if the object returns itself in response to class.

乔的回答很好。在大多数情况下,一个简单的替代方法是检查对象是否返回自身以响应class.

if ([obj class] == obj) { … }

This works because the NSObjectmeta-class overrides classand returns the class object (itself) — see the NSObject Class Reference. This does not require the runtime headers, but assumes the objects are subclasses of NSObjectand don't override -classor +classand do something unusual.

这是有效的,因为NSObject元类覆盖class并返回类对象(本身)——请参阅NSObject 类参考。这不需要运行时标头,但假设对象是 的子类,NSObject并且不会覆盖-class+class做一些不寻常的事情。



With the input in the question, the results are the same as Joe's:

在问题中输入后,结果与 Joe 的相同:

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);
    }
}

Class: NSObject
Class: NSValue
Class: NSNumber
Class: NSPredicate
Instance: not a class object

类:NSObject
类:NSValue
类:NSNumber
类:NSPredicate
实例:不是类对象

回答by Deepak Danduprolu

If you need to verify if the object in the array is a Classobject then you can verify if it responds to class methods.

如果需要验证数组中的Class对象是否为对象,则可以验证它是否响应类方法。

for ( id obj in arr ) {
    if (([obj respondsToSelector:@selector(isSubclassOfClass:)])
          && (obj == [NSObject class]) ) {
        NSLog(@"%@", obj);
    }
}

Once you know it is a Classobject by verifying if it responds to isSubclassOfClass:then you can check for direct equality with [NSObject class].

一旦您Class通过验证它是否响应来知道它是一个对象,isSubclassOfClass:那么您就可以检查与[NSObject class].

回答by Cyprian

No problem here is how you do it:

没有问题的是你如何做到这一点:

if([NSStringFromClass([obj class]) isEqualToString:@"Class"]){
    NSLog(@"It is type of Class");
}

Edit

编辑

Or you can make your Class conform to a protocol: and check if obj that you get from the array conforms to this protocol like this:

或者你可以让你的类符合一个协议:并检查你从数组中获得的 obj 是否符合这个协议,如下所示:

if([obj conformsToProtocol:@protocol(MyClassProtocol)])

Edit

编辑

Or you can check if what you get from the array is an NSObject complient

或者您可以检查从数组中获得的内容是否符合 NSObject

if ([object conformsToProtocol:@protocol(NSObject)]) {
    // Do something
}