2009-07-22 8 views
1

Ich war kürzlich von einigen unerwarteten Kompilierungsfehlern in meinem Code sehr verwirrt. Ich habe einige Fehlersuche, und ich kam mit diesem Stück Testcode auf:Ergebnisse für performSelector: unterscheiden sich von Standard Punktnotation Anruf?

1 float performSelectorResult, messageResult; 
2 SEL selector = @selector(smallContentCellMargin); 
3 
4 NSLog (@"selector %s result %f", selector, [defaults performSelector:selector]); 
5 NSLog (@"message result is %f", defaults.smallContentCellMargin); 
6 
7 performSelectorResult = [defaults performSelector:selector]; 
8 messageResult = defaults.smallContentCellMargin; 

Wenn ich den Code ausführen wie sie ist, ich einen Compiler-Fehler in Zeile 7 erhalten: „inkompatible Typen in Zuweisung“. Wenn ich jedoch Zeile 7 auskommentiere, wird der Code erstellt und ausgeführt; Die Ergebnisse in NSLog sind:

2009-07-21 18:31:44.823 ICE[24347:20b] selector smallContentCellMargin result 0.000000 
2009-07-21 18:31:44.830 ICE[24347:20b] message result is 7.000000 

Ich habe sehr ähnlichen Code verwendet, um ein UIFont, aber nie ein Float abrufen. Gibt es etwas, das ich nicht kenne, oder ist das ein Fehler in Objective-C? Ich bin sehr verwirrt.

Antwort

3

Zuerst behandeln Sie einen Selektor als eine Zeichenfolge beim Protokollieren mit NSLog. Tun Sie das nicht - ein SEL ist keine Zeichenkette. Verwenden Sie das% @ -Format und NSStringFromSelector (aSelector).

Für das vorliegende Problem ist -performSelector: definiert, um mit jedem Selektor zu arbeiten, der einen Objektrückgabetyp hat. Aufgrund der ABI können Sie diese für int-Rückgabetypen bis zur Größe eines Zeigers verwenden (abhängig von den Details der Laufzeitimplementierung), aber Sie kommen normalerweise nicht mit Floating-Rückgabewerten davon durch, wie Sie bemerkt haben.

Für Nicht-Objekt-Rückgabewerte sollten Sie NSInvocation oder -valueForKey: verwenden. Im letzteren Fall erhalten Sie eine Float-Box als NSNummer.

+0

Ich habe einen schnellen Test von -valueForKey versucht: 'float quickTest = [defaults valueForKey: @ "smallContentCellMargin"];' Wenn ich versuche, den Code zu kompilieren, erhalte ich einen Fehler "inkompatible Typen in der Initialisierung". Ich habe in der Dokumentation nach -valueForKey gesucht, und es heißt, dass es den Typ (id) zurückgibt - habe ich etwas falsch gemacht, oder ist es in diesem Fall dasselbe wie -performSelector? – JoBu1324

+2

+1 Dies ist eine gute Gelegenheit, mehr darüber zu erfahren, wie Nachrichten tatsächlich übermittelt werden. Wir sagen oft, dass Nachrichten mit objc_msgSend() übergeben werden, aber das ist eine Vereinfachung. Suchen Sie in der Dokumentation nach objc_msgSend() und vergleichen Sie sie mit ihren Freunden, in diesem Fall objc_msgSend_fpret(). Beachten Sie, dass der OP-Code * auf PPC funktioniert, aber nicht auf Intel. Und das ist die Art von Plattformabhängigkeit, auf die Sie sich nicht verlassen wollen. Verwenden Sie Jims Ansatz, sogar für Ints, wo Sie mit Intel davonkommen können. –

+0

Lies Jims Kommentar über -valueForKey erneut: gib eine NSNummer zurück. NSNumber ist ein Objekt, das eine Zahl darstellt (in diesem Fall ein Doppel). –

Verwandte Themen