如何检查一个id是一个实例还是一个class?

How to check if an id is an instance or a class?

说我有一个方法:

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

我们都知道 Objective-C classes 或对象也是如此。所以我一直想知道如何确定在方法内部传递的 id 是 class 的 INSTANCE 还是 CLASS 本身?因为它可以像这样使用:

[object method:[NSObject new]];

或:

[object method:[NSObject class]];

如何知道传递的参数是一个实例?我无法仅通过发送 class 消息来检查它,因为对于 class 它将 return 与实例

相同的结果

已编辑

Alexander 提供的方法不适合我,因为我不知道 class 会通过什么,所以我无法检查特定 class 的成员资格。我只需要知道它是 class(无论 class)还是实例(无论 class)

类 return self 来自 class 消息,实例 return 他们的 class。所以只需测试 class 的结果是否与接收者相同:

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

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

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

  2. 如果 class return self 代码将中断。 classes 正在观察的对象 (KVO) 可能就是这种情况。并不少见。

以下代码始终有效并且不受这些问题的影响:

#import <objc/runtime.h>

- (void)method:(id)anObject
{
    if (class_isMetaClass(object_getClass(obj))) {
        // it's a class
    } else {
        // it's an instance
    }
}