NSMutableDictionary的isKindOfClass NSDictionary是false。

4
以下代码片段为什么只打印blah3和blah4,而不是blah2?
isKindOfClass应该尊重继承关系,但它似乎未能做到这一点。
Obj-C:
NSDictionary *dict = [NSDictionary new];
NSMutableDictionary *mutableDict = [NSMutableDictionary new];

if([dict isKindOfClass:[mutableDict class]]){
    NSLog(@"blah"); //does not print (as expected)
}

if([mutableDict isKindOfClass:[dict class]]){
    NSLog(@"blah2"); //does not print (unexpected!)
}

if([mutableDict isKindOfClass:[mutableDict class]]){
    NSLog(@"blah3"); //prints
}

if([dict isKindOfClass:[dict class]]){
    NSLog(@"blah4"); //prints
}

Swift:

var dict = NSDictionary()
var mutableDict = NSMutableDictionary()
if(dict.isKindOfClass(mutableDict.dynamicType)) {print("blah")}
if(mutableDict.isKindOfClass(dict.dynamicType)) {print("blah2")} 
if(dict.isKindOfClass(dict.dynamicType)) {print("blah3")}
if(mutableDict.isKindOfClass(mutableDict.dynamicType)) {print("blah4")} 

使用Xcode 7.3.1,iOS 9.3。
1个回答

4
原因是,NSDictionary.new 不能保证返回一个 NSDictionary 对象 - 它可以返回它的子类。而你的字典恰好是其中一个子类,如 NSDictionary0。另外,可变的那个字典可能是 NSMutableDictionary 的一个子类,如 NSMutableDictionaryM
所以,你的 NSMutableDictionary 确实是一个 NSDictionary,但它并没有继承自其他子类。
你可以使用 isKindOf:[NSDictionary class] 进行简单的检查。你可能想要输出或查看具体对象的类,并会感到惊讶。
附注:这里有一个快速且简单的类图: enter image description here 如你所见,两者互不相关,虽然都是 NSDictionary
这被称为“类簇”,有一些棘手的含义。另一个著名的例子是 NSString,它的类通常不是新手所期望的那样。

来自文档的信息:如果接收器是aClass的实例或任何继承自aClass的类的实例,则为YES,否则为NO。https://developer.apple.com/reference/objectivec/1418956-nsobject/1418511-iskindofclass - Alexander
1
@Eiko NSMutableDictionaryNSDictionary的子类,因此isKindOf将返回true,并且应该打印出blah2 - Alexander
@AMomchilov 但他并没有将其与[NSDictionary class]进行比较,而是与[dict class]进行比较。并且dict不是NSDictionary本身,它是它的一个子类,不在NSDictionary的继承层次结构中。只需执行NSLog("%@", dict.class); 并自己查看即可! - Eiko
Eiko,如果你能澄清你的回答,我会接受你的回答,而不是那个更清晰但只是复制了你的人的回答。 - user1366911
1
添加了一些更多的解释和一个图表。 - Eiko
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接