2016-06-30 17 views
3

Warum ist das folgende Code-Snippet NUR Drucken blah3 und blah4, aber nicht blah2?NSMutableDictionary isKindOfClass NSDictionary ist falsch

isKindOfClass soll die Vererbung respektieren, aber genau das scheint genau zu sein.

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")} 

Mit Xcode 7.3.1, IOS 9.3.

Antwort

3

Der Grund ist, NSDictionary.new ist nicht garantiert, eine NSDictionary selbst zurückzugeben - es kann eine Unterklasse davon zurückgeben. Und Ihr Diktat gehört zu einer Unterklasse wie NSDictionary0. Auch die veränderbare ist wahrscheinlich von einer Unterklasse von NSMutableDictionary, wie NSMutableDictionaryM.

So ist Ihr NSMutableDictionary in der Tat ein NSDictionary, aber es erbt nicht von dieser anderen Unterklasse.

Sie können einfach mit isKindOf:[NSDictionary class] stattdessen überprüfen. Vielleicht möchten Sie die Klassen Ihrer konkreten Objekte löschen oder überprüfen und überrascht sein.

Edit: hier ist eine schnelle und schmutzige Klassendiagramm: enter image description here

Wie Sie sehen können, ist man nicht „Art“ eine andere, obwohl beide NSDictionary sind.

Dies wird als "Klassencluster" bezeichnet und hat einige knifflige Auswirkungen. NSString ist eine andere berühmte, wo die Klassen selten sind, was Neulinge erwarten.

+0

Nicht sicher, was Sie sagen. Wenn NSMutableDictionary ein NSDictionary ist, warum sollte blah2 nicht gedruckt werden? – user1366911

+0

Weil Sie gegen 'dict.class' vergleichen. Aber dict ist nicht 'NSDictionary', sondern eine Unterklasse davon. – Eiko

+0

Wie wäre es mit dem Anwendungsfall, wo ich zwei IDs habe und ich möchte überprüfen, ob die Klassen gleich oder eine Unterklasse sind. In diesem Fall muss ich isKindOfClass verwenden. Ich kann nicht direkt mit [NSDictionary-Klasse] vergleichen. Dies ist der Zweck von isKindOfClass, nein? – user1366911

Verwandte Themen