NSLog(...) غير لائق شكل محدد يؤثر على غيرها من المتغيرات ؟
-
22-07-2019 - |
سؤال
كنت مؤخرا قد يضيع حوالي نصف ساعة تعقب هذا السلوك الغريب في NSLog(...):
NSString *text = @"abc";
long long num = 123;
NSLog(@"num=%lld, text=%@",num,text); //(A)
NSLog(@"num=%d, text=%@",num,text); //(B)
الخط (أ) يطبع المتوقع "num=123, text=اي بي سي" ، ولكن خط (ب) مطبوعات "num=123, text=(null)".
ومن الواضح طباعة long long
مع %d
هو خطأ ، ولكن يمكن للشخص أن يفسر السبب في أنه من شأنه أن يسبب text
سيتم طباعتها كما null?
المحلول
كنت مجرد عبث الذاكرة المحاذاة على المكدس.أعتقد من أنك تستخدم أحدث منتجات أبل مع معالج 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).
في النهاية لأن الهدف-C هو فقط ج مع إضافات المتصل ينظف كل هذه الفوضى.
نصائح أخرى
كيف varargs تنفذ تعتمد على النظام.ولكن ما هو المرجح أن يحدث هو أن الحجج التي يتم تخزينها consecutivelyly في منطقة عازلة ، على الرغم من الحجج التي قد تكون مختلفة الأحجام.لذا فإن أول 8 بايت (على افتراض أن حجم long long int
) من الحجج long long int
, وبعد 4 بايت (على افتراض أن حجم مؤشر على النظام الخاص بك) ، NSString
مؤشر.
ثم عندما كنت أقول وظيفة أنه يتوقع int
ثم مؤشر ، نتوقع أول 4 بايت إلى int
(على افتراض أن حجم int
) و 4 بايت إلى أن المؤشر.بسبب endianness وترتيب الحجج على النظام الخاص بك ، أول 4 بايت long long int
يحدث أن تكون أقل أهمية بايت من عدد لذا فإنه يطبع 123.ثم مؤشر كائن يقرأ 4 بايت ، وهو في هذه الحالة هو أهم بايت من رقم هاتفك الذي هو 0 ، بحيث يحصل تفسيره nil
مؤشر.الفعلية المؤشر لم يحصل القراءة.