我只有一个Class字符串的映射,用于确定字符串表示的Class是否继承自另一个Class。我知道我可以在对象的实例上使用isKindOfClass,但我不知道如何使用Class。所以我想做点像......
NSString *className = [self.classMapping objectForKey:key];
Class class = NSClassFromString(className);
if (/* class inherits from ClassA */)
ClassA *classA = [[ClassA alloc] initWithClassAInitializer];
else if (/* class inherits from ClassB */)
ClassB *classB = [[ClassB alloc] initWithClassBInitializer];
...但我不知道if语句中有什么内容。如何使用Class来确定它是否继承自另一个类?
提前感谢您的智慧!
答案 0 :(得分:0)
这些检查是不必要的,您只需在类本身上调用alloc
即可获得所需的初始化。
Class class = NSClassFromString(className)
id object = [[class alloc] init];
这里的id可以替换为所有这些类继承的根类。如果可能,您的子类应该都使用通用的init方法,在自己的init中为超级init提供任何附加功能。这样可以避免进行这些检查。
答案 1 :(得分:0)
正如评论中所指出的,您可以在类对象上使用NSObject
继承方法。您还可以直接比较类对象的相等性:
Class c = NSClassFromString(className);
if( c == [ClassA class] ){
/* create instance of ClassA */
}
else if ...
答案 2 :(得分:0)
最简单的方法:Class
是一个对象,所以你可以这样做:
NSLog(@"%d", [[@"Test" class] isSubclassOfClass:[NSString class]]);
NSLog(@"%d", [[@"Test" class] isSubclassOfClass:[NSObject class]]);
NSLog(@"%d", [[@"Test" class] isSubclassOfClass:[NSArray class]]);
您也可以使用低级Objective-C运行时函数来解决这个问题:
#import <objc/runtime.h>
BOOL isClassSubclassOf(Class classToTest, Class maybeParentClass)
{
do {
if (classToTest == maybeParentClass) {
return YES;
}
classToTest = class_getSuperclass(classToTest);
} while (classToTest != NULL);
return NO;
}
int main(int argc, char *argv[]){
@autoreleasepool{
NSLog(@"%d", isClassSubclassOf([@"Test" class], [NSString class]));
NSLog(@"%d", isClassSubclassOf([@"Test" class], [NSObject class]));
NSLog(@"%d", isClassSubclassOf([@"Test" class], [NSArray class]));
}
}
最后但并非最不重要的是,如果初始化程序名称不同/唯一,您也可以使用ducktyping:
Class klass;
id obj = nil;
klass = [NSString class];
// klass = [NSArray class];
if (class_getInstanceMethod(klass, @selector(initWithFormat:))) {
obj = [[klass alloc] initWithFormat:@"It's string-like!"];
} else if (class_getInstanceMethod(klass, @selector(initWithObjects:))) {
obj = [[klass alloc] initWithObjects:@"It's", @"array-like", nil];
}
NSLog(@"%@", obj);
按原样,您将收到日志消息It's string-like!
,但如果您取消注释注释行,则会获得( "It's", "array-like" )
。