Frage

Okay, ich habe das Gefühl, dass Sie schnell guys'll der Lage sein, darauf hinzuweisen, warum ich darüber so verwirrt, aber ich habe eine Frage, warum die folgenden führt nicht zu einem Compiler-Fehler oder Warnung:

NSString * intValue = [ NSString stringWithFormat:@"int = %i", [ [ self.selectedObject valueForKey:name ] integerValue ] ];

selectedObject ist ein NSObject und name geschieht der Name eines @property vom Typ int sein.

Was mich verwirrt ist, warum der Compiler durchaus bereit ist anzunehmen, dass das Rückergebnis von [ self.selectedObject valueForKey:name ] vom Typ NSNumber * ist (ohne es zu typecasting), um Kette die Nachricht mit einem Aufruf an integerValue.

Offensichtlich KVC hüllt Nicht-Objekt „Nummer“ Typen in NSNumber, aber es gibt keine Möglichkeit für den Compiler, dass -valueForKey: zu wissen, wird ein NSNumber * in diesem speziellen Fall zurück.

Warum funktioniert dieses Ergebnis in einer Compiler-Warnung entlang der Linien von „id kann nicht reagieren auf‚-integerValue‘“?

War es hilfreich?

Lösung

Ich hoffe, dass ich es richtig: Das liegt daran, id ist „special“. Objekte des id Typ kann jede gewünschte Nachricht gesendet werden, gibt es keine Überprüfung durch den Compiler und alles wird geprüft, im laufenden Betrieb geschehen ist. Oder, mit anderen Worten, die id Art ist die „dynamische Typisierung“ Teil von Objective-C, während alle anderen Arten (wie NSObject) die „statische Typisierung“ Teil sind.

Auf diese Weise können Sie wählen, wo Sie statische Typisierung verwenden wollen, und wo Sie dynamische Eingabe verwenden möchten. Es ist völlig legal, so etwas zu tun:

id str1 = @"Hello";
id str2 = [str1 stringByAppendingString:@", world"];

Aber man in der Regel die Saiten Typ „fest“, wie NSStrings, weil Sie die Bequemlichkeit der Kompilierung-statische Typprüfung erhalten, und nur auf dynamische Typisierung zurückgreifen, wo die statische in die Quere kommen würde, wie in der valueForKey Situation.

Andere Tipps

Die Zeit ist vergangen und wir haben eine bessere Typinferenz jetzt dank der __auto_type da Xcode verfügbar 8. So, jetzt können Sie tun,

#define let __auto_type const
#define var __auto_type

let a = @[@"pew pew"];
var b = 2;
b = a; //compiler warning "Incompatible pointer to integer conversion assigning to 'int' from 'NSArray *__strong const'"

und viel mehr

In der Tat, ich mochte das so sehr, ich dies als pod für Bequemlichkeit gemacht.

pod 'SwiftyObjC'
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top