如何检查id是实例还是类?

时间:2015-02-12 09:04:31

标签: objective-c cocoa

说我有方法:

- (void)method:(id)anObject
{
  // do something
}

我们都知道Objective-C类或对象。所以我一直想知道如何确定id在方法中传递了一个类或一个CLASS本身的INSTANCE?因为它可以像以下一样使用:

[object method:[NSObject new]];

或:

[object method:[NSObject class]];

我怎样才能发现传递的参数是一个实例?我只能通过发送class消息来检查它,因为对于一个类,它将返回与实例相同的结果

EDITED

亚历山大提供的方法不适合我,因为我不知道将通过什么课程,所以我无法检查特定班级的成员资格。我只需要知道它是一个类(无论是什么类)或者是一个实例(无论是什么类)

1 个答案:

答案 0 :(得分:4)

类从self消息返回class,实例返回其类。因此,只测试class的结果是否与接收者相同:

- (void)method:(id)anObject
{
    if (anObject == [anObject class]) {
        // it's a class
    } else {
        // it's an instance
    }
}

编辑:虽然简单,但上述代码有两个微妙的问题:

  1. 接收方必须实施class。所有NSObject(和NSProxy)派生类都这样做,但对于自定义根类,情况可能并非如此。非常罕见。

  2. 如果某个类返回self,则代码会中断。这可能是被观察对象类(KVO)的情况。不那么罕见。

  3. 这里的代码将始终有效并且不受这些问题的影响:

    #import <objc/runtime.h>
    
    - (void)method:(id)anObject
    {
        if (class_isMetaClass(object_getClass(obj))) {
            // it's a class
        } else {
            // it's an instance
        }
    }