Frage

Ich habe vor kurzem verschwendet etwa eine halbe Stunde nach unten Verfolgung dieses seltsame Verhalten in NSLog (...):

NSString *text = @"abc";
long long num = 123;
NSLog(@"num=%lld, text=%@",num,text); //(A)
NSLog(@"num=%d, text=%@",num,text); //(B)

Line (A) druckt den erwarteten "num = 123, text = abc", aber Linie (B) druckt "num = 123, text = (null) ".

Offensichtlich ein long long mit %d Druck ist ein Fehler, aber kann jemand erklären, warum es dazu führen, text als null gedruckt werden?

War es hilfreich?

Lösung

Sie haben soeben Speicherausrichtung auf dem Stapel vermasselt. Ich gehe davon aus, als Sie neuestes Apple-Produkt mit x86-Prozessor verwenden. Wenn man diese Annahmen berücksichtigt Ihr Stack aussieht, dass in beiden Fällen:

   |      stack          | first | second |
   +---------------------+-------+--------+
   |        123          |       |  %d    |
   +---------------------+ %lld  +--------+
   |         0           |       |  %@    |
   +---------------------+-------+--------+
   |   pointer to text   | %@    |ignored |
   +---------------------+-------+--------+  

In ersten Fall setzen Sie auf Stapel 8 Bytes und dann 4 Bytes. Und als NSLog wird angewiesen, zurück vom Stapel 12 Byte (8 Byte für %lld und 4 Bytes für %@) zu übernehmen.

In zweiter Situation, die Sie NSLog anweisen ersten 4 Bytes nehmen (%d). Da Ihre Variable ist 8 Byte lang und hält wirklich kleine Anzahl seiner oberen 4 Bytes 0. Dann, wenn NSLog versuchen, Text drucken es nil vom Stapel nehmen.

Da Nachricht an nil Senden gilt in Obj-C NSLog wird nur description: senden nil bekommen wahrscheinlich nichts und dann drucken (null).

Am Ende da Objective-C nur C mit Zusätzen ist, reinigen Anrufer bis ganzem dieses Chaos.

Andere Tipps

Wie varargs implementiert werden, ist systemabhängig. Aber was wahrscheinlich passiert ist, dass die Argumente consecutivelyly in einem Puffer gespeichert werden, auch wenn die Argumente unterschiedlich groß sein können. So ist das erste 8 Bytes (unter der Annahme, das ist die Größe eines long long int) des Arguments ist die long long int und das nächste 4 Bytes (vorausgesetzt, das ist die Größe eines Zeigers auf dem System) wird die NSString Zeiger.

Wenn Sie dann die Funktion sagen, dass es eine int und dann einen Zeiger erwartet, erwarten, dass es die ersten 4 Bytes der int sein (unter der Annahme, das ist die Größe eines int) und die nächsten 4 Bytes der Zeiger zu sein. Aufgrund der besonderen endianness und Anordnung von Argumenten auf Ihrem System, das erste 4 Bytes des long long int geschieht die am wenigsten signifikante Bytes Ihrer Zahl sein, so dass er druckt 123. Dann für den Objektzeiger, liest er das nächste 4 Bytes, die in diesem Fall ist das höchstwertigen Bytes Ihrer Zahl, die alle gleich 0, so dass als nil Zeiger interpretiert wird. Der eigentliche Zeiger wird nie gelesen.

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