iOS:如何判断类型为 id 的对象是 class 还是协议
iOS: How to tell if an object of type id is a class or a protocol
这是非常高级的东西。我正在处理一些运行时代码作为一个副项目。我要解决的问题是:如果我有一个 id 类型的对象,并且该对象可以是字符串或 class 或协议,我怎么知道它是什么?
例如,这是我正在处理的一些代码:
[objArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[NSString class]]) {
// Do something with the string ...
} else if (... obj is a Protocol ...) {
// Do something with the protocol ...
} else if (... obj is a Class ...) {
// Do something with the class ...
} else {
// It's something we are not interested in!
}
}];
到目前为止,我在数组中存储各种 NSString、Class 和 Protocol 实例时没有遇到任何问题,其他一切都很好。我需要检测它们的原因很简单,我无法控制这段代码中的内容。所以我需要先确定循环正在处理的 obj
是什么,然后再使用它。
我一直在尝试各种运行时函数和东西,但到目前为止,如果确定对象是什么,我还没有成功。
有人试过这样的东西吗?
我现在可能找到了解决方案。
测试一个id是否为Class:
NSLog(@"isClass %s", object_isClass(obj) ? "yes":"no");
测试一个 id 是否是一个协议:
NSLog(@"isProtocol %s", object_getClass(obj) == objc_getClass("Protocol") ? "yes":"NO");
这些似乎有效,但我认为可能有更好的方法来进行协议检查。
因为 Protocol 是 NSObject 的子class,你可以像检测任何其他 class。有趣的是 Protocol class 没有 public 接口。
id 类型的对象是 Class 或 class 的实例,所以我会测试它是否是 Class 首先,如果失败,它是 class 的一个实例,因此使用字符串比较来确定 class 名称。对于 Protocol 与 @"Protocol"
比较
示例-
// assign the object to inspect
id obj = //...
NSString *className;
// test for Class type first
if (object_isClass(obj)) {
// it's a Class... inspect further...
className = NSStringFromClass(obj);
if ([className isEqualToString:@"Protocol"]) { /* Protocol Class */ }
}
else {
// must be an instance - get the class name
className = NSStringFromClass([obj class]);
// test for instance of Protocol class
if ([className isEqualToString:@"Protocol"]) { /* Protocol instance */ }
// continue testing for any other classes here...
}
NSStringFromClass 在 Foundation Functions Reference
中找到
这是非常高级的东西。我正在处理一些运行时代码作为一个副项目。我要解决的问题是:如果我有一个 id 类型的对象,并且该对象可以是字符串或 class 或协议,我怎么知道它是什么?
例如,这是我正在处理的一些代码:
[objArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[NSString class]]) {
// Do something with the string ...
} else if (... obj is a Protocol ...) {
// Do something with the protocol ...
} else if (... obj is a Class ...) {
// Do something with the class ...
} else {
// It's something we are not interested in!
}
}];
到目前为止,我在数组中存储各种 NSString、Class 和 Protocol 实例时没有遇到任何问题,其他一切都很好。我需要检测它们的原因很简单,我无法控制这段代码中的内容。所以我需要先确定循环正在处理的 obj
是什么,然后再使用它。
我一直在尝试各种运行时函数和东西,但到目前为止,如果确定对象是什么,我还没有成功。
有人试过这样的东西吗?
我现在可能找到了解决方案。
测试一个id是否为Class:
NSLog(@"isClass %s", object_isClass(obj) ? "yes":"no");
测试一个 id 是否是一个协议:
NSLog(@"isProtocol %s", object_getClass(obj) == objc_getClass("Protocol") ? "yes":"NO");
这些似乎有效,但我认为可能有更好的方法来进行协议检查。
因为 Protocol 是 NSObject 的子class,你可以像检测任何其他 class。有趣的是 Protocol class 没有 public 接口。
id 类型的对象是 Class 或 class 的实例,所以我会测试它是否是 Class 首先,如果失败,它是 class 的一个实例,因此使用字符串比较来确定 class 名称。对于 Protocol 与 @"Protocol"
比较示例-
// assign the object to inspect
id obj = //...
NSString *className;
// test for Class type first
if (object_isClass(obj)) {
// it's a Class... inspect further...
className = NSStringFromClass(obj);
if ([className isEqualToString:@"Protocol"]) { /* Protocol Class */ }
}
else {
// must be an instance - get the class name
className = NSStringFromClass([obj class]);
// test for instance of Protocol class
if ([className isEqualToString:@"Protocol"]) { /* Protocol instance */ }
// continue testing for any other classes here...
}
NSStringFromClass 在 Foundation Functions Reference
中找到