Вы только что испортили выравнивание памяти в вашем стеке. Я предполагаю, что вы используете новейший продукт Apple с процессором x86. С учетом этих предположений ваш стек выглядит так в обеих ситуациях:
| stack | first | second |
+---------------------+-------+--------+
| 123 | | %d |
+---------------------+ %lld +--------+
| 0 | | %@ |
+---------------------+-------+--------+
| pointer to text | %@ |ignored |
+---------------------+-------+--------+
В первой ситуации вы кладете в стек 8 байтов, а затем 4 байта. И затем NSLog получает команду извлечь из стека 12 байтов (8 байтов для %lld
и 4 байта для %@
).
Во второй ситуации вы указываете NSLog сначала взять 4 байта (%d
). Поскольку ваша переменная имеет длину 8 байт и содержит действительно небольшое число, ее верхние 4 байта будут равны 0. Тогда, когда NSLog попытается напечатать текст, он возьмет nil
из стека.
Поскольку отправка сообщения на nil
действительна в Obj-C, NSLog просто отправит description:
на nil
, вероятно, ничего не получит, а затем выведет (null).
В конце концов, поскольку Objective-C - это просто C с добавлениями, вызывающая сторона устраняет весь этот беспорядок.