[英]Check if object is Class type
我有一个接收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 class,它是一个结构,所以我不能只使用
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
于NSObject
检查
要确定“对象”是 class 还是实例,您需要在两阶段过程中检查它是否是元 class 。 首先调用object_getClass
然后使用 class_isMetaClass 检查它是否是元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));
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];
和 output:
Class:NSObject
Class:NSValue
Class:NSNumber
Class:NSPredicate
实例:不是 class object
更新:在 iOS 8+ 或 OS X 10.10+ 中,您可以这样做:
object_isClass(obj)
(您需要#import <objc/runtime.h>
。)
乔的回答很好。 在大多数情况下有效的一个简单替代方法是检查 object 是否返回自身以响应class
。
if ([obj class] == obj) { … }
这是因为NSObject
元类覆盖class
并返回 class object (本身) - 请参阅NSObject Z9BD781329FEDBEBF6AFE23 这不需要运行时标头,但假定对象是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);
}
}
Class:NSObject
Class:NSValue
Class:NSNumber
Class:NSPredicate
实例:不是 class object
如果需要验证数组中的 object 是否为Class
object 则可以验证它是否响应 ZA2F2ED4F8EBC2CBB4DZ21A2 方法。
for ( id obj in arr ) {
if (([obj respondsToSelector:@selector(isSubclassOfClass:)])
&& (obj == [NSObject class]) ) {
NSLog(@"%@", obj);
}
}
一旦你知道它是一个Class
object 通过验证它是否响应isSubclassOfClass:
然后你可以检查与[NSObject class]
的直接相等性。
细节来了。
首先,在objc.h
中,我们可以找到这些代码:
/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;
这意味着所有Objective-C class
都是Class
类型,包括NSObject
。
所以你的问题:
[arr addObject:[NSObject class]]; /// YES
[arr addObject:[NSValue class]]; /// YES
[arr addObject:[NSNumber class]]; /// YES
[arr addObject:[NSPredicate class]]; /// YES
[arr addObject:@"not a class object"]; /// NO, It's just a NSString.
其次,正如您所提到的,“ Class
不是objective-c class
,它是一个结构”。 我想解释一下objective-c class
class 实际上是 C 中的Struct
。
在runtime.h
中,我找到了这些代码,也许对我们有帮助:
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE;
const char *name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
struct objc_cache *cache OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
最后我们来看看NSObject.h
line30--32
,这三个方法。 我们可以知道aClass
是Class
类型。 这进一步说明所有 objective-c class 都是Class
类型。
- (BOOL)isKindOfClass:(Class)aClass;
- (BOOL)isMemberOfClass:(Class)aClass;
- (BOOL)conformsToProtocol:(Protocol *)aProtocol;
这几乎是我第一次用我蹩脚的英语回答问题。 如果您还有任何问题,请尽快回复,我会尽力解释。 而且我还建议你阅读NSObject.h
、 runtime.h
、 objc.h
代码,也许它会对你有所帮助。
这里没有问题是你如何做到的:
if([NSStringFromClass([obj class]) isEqualToString:@"Class"]){
NSLog(@"It is type of Class");
}
编辑
或者您可以使您的 Class 符合协议:并检查您从数组中获得的 obj 是否符合此协议,如下所示:
if([obj conformsToProtocol:@protocol(MyClassProtocol)])
编辑
或者您可以检查从数组中获得的内容是否符合 NSObject
if ([object conformsToProtocol:@protocol(NSObject)]) {
// Do something
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.