سؤال

أنا أتعلم الهدف-C و الكاكاو و قد تأتي عبر هذا البيان:

الكاكاو الأطر نتوقع أن العالمية ثوابت السلسلة بدلا من سلسلة حرفية تستخدم القاموس مفاتيح الإخطار أسماء الاستثناء ، وبعض معلمات الأسلوب أن تأخذ السلاسل.

لقد عملت فقط في أعلى مستوى اللغات حتى لم تنظر في تفاصيل سلاسل ذلك بكثير.ما الفرق بين سلسلة مستمرة سلسلة حرفية ؟

هل كانت مفيدة؟

المحلول

في الهدف جيم, جملة @"foo" هو غير قابل للتغيير, الحرفي مثيل NSString.لا تجعل سلسلة ثابتة من سلسلة حرفية كما مايك نفترض.

الهدف-C المجمعين عادة هل المتدرب الحرفي السلاسل في تجميع الوحدات — فإنها تتجمع استخدامات متعددة من نفس سلسلة حرفية و انها ممكن رابط للقيام إضافية تتدرب عبر تجميع الوحدات التي ترتبط مباشرة إلى ثنائي واحد.(منذ الكاكاو يميز بين قابلة للتغيير وغير قابل للتغيير سلاسل ، سلاسل حرفية دائما أيضا ثابتة ، وهذا يمكن أن تكون واضحة و آمن.)

ثابت سلاسل من ناحية أخرى عادة ما أعلن محددة باستخدام بناء جملة مثل هذه:

// MyExample.h - declaration, other code references this
extern NSString * const MyExampleNotification;

// MyExample.m - definition, compiled for other code to reference
NSString * const MyExampleNotification = @"MyExampleNotification";

نقطة النحوية ممارسة هنا هو أنه يمكنك جعل الاستخدامات سلسلة فعالة من خلال ضمان أن هناك مثيل واحد فقط من هذه السلسلة في استخدام حتى عبر أطر متعددة (المكتبات المشتركة) في نفس مساحة العنوان.(موضع const الكلمة المسائل ؛ فإنه يضمن أن المؤشر نفسه هو ضمان أن تكون ثابتة.)

في حين حرق الذاكرة ليست صفقة كبيرة كما كان في أيام 25MHz 68030 محطات العمل مع 8MB من ذاكرة الوصول العشوائي ، مقارنة سلاسل المساواة يمكن أن يستغرق وقتا طويلا.ضمان أن معظم الوقت السلاسل التي هي على قدم المساواة كما سيتم مؤشر المساواة يساعد.

مثلا كنت ترغب في الاشتراك في الإخطارات من كائن بالاسم.إذا كنت تستخدم غير ثابت سلاسل الأسماء ، NSNotificationCenter نشر الإخطار يمكن أن تصل الرياح تفعل الكثير من بايت بايت سلسلة المقارنات عند تحديد من هو ترغب في ذلك.إذا كان معظم هذه المقارنات تماس لأن الجمل يجري مقارنة بنفس المؤشر ، التي يمكن أن يكون فوز كبير.

نصائح أخرى

بعض التعاريف

A الحرفي هو قيمة ، وهو غير قابل للتغيير حسب التعريف.على سبيل المثال: 10
A ثابت هو للقراءة فقط متغير أو مؤشر.على سبيل المثال: const int age = 10;
A سلسلة حرفية هو التعبير مثل @"".مترجم محل هذا مع مثيل NSString.
A سلسلة المستمر هو للقراءة فقط مؤشر إلى NSString.على سبيل المثال: NSString *const name = @"John";

بعض التعليقات على السطر الأخير:

  • هذا هو مؤشر ثابت وليس كائن ثابت1. objc_sendMsg2 لا يهمني إذا كنت مؤهلا الكائن مع const.إذا كنت تريد كائن غير قابل للتغيير ، يجب أن التعليمات البرمجية التي ثبات داخل الكائن3.
  • كل @"" التعابير هي في الواقع ثابتة.يتم استبدال4 في وقت الترجمة مع حالات NSConstantString, التي هي متخصصة فرعية من NSString مع الذاكرة الثابتة تخطيط5.وهذا ما يفسر أيضا لماذا NSString هو الكائن الوحيد الذي يمكن تهيئة في وقت الترجمة6.

A سلسلة ثابتة سيكون const NSString* name = @"John"; وهو ما يعادل NSString const* name= @"John";.هنا كل جملة و مبرمج نية خاطئة: const <object> هو تجاهلها ، NSString سبيل المثال (NSConstantString) كان بالفعل غير قابل للتغيير.

1 الكلمة const ينطبق ينطبق على كل ما هو على الفور إلى اليسار.إذا كان هناك أي شيء إلى اليسار ، وهو ينطبق على كل ما هو على الفور إلى الحق.

2 هذه هي وظيفة هذا وقت التشغيل يستخدم لإرسال جميع الرسائل في الهدف جيم, وبالتالي ما يمكنك استخدامها لتغيير حالة كائن.

3 على سبيل المثال:في const NSMutableArray *array = [NSMutableArray new]; [array removeAllObjects]; const لا يمنع البيان الأخير.

4 على LLVM رمز أن يعيد كتابة التعبير RewriteModernObjC::RewriteObjCStringLiteral في RewriteModernObjC.cpp.

5 لمشاهدة NSConstantString تعريف cmd+انقر في كسكودي.

6 إنشاء تجميع الوقت الثوابت لفئات أخرى سيكون من السهل لكنه يحتاج المترجم إلى استخدام المتخصصة فرعية.هذا من شأنه كسر التوافق مع كبار السن الهدف-C الإصدارات.


إلى الاقتباس

الكاكاو الأطر نتوقع أن العالمية ثوابت السلسلة بدلا من سلسلة حرفية تستخدم القاموس مفاتيح الإعلام ، استثناء أسماء بعض معلمات الأسلوب أن تأخذ السلاسل.لك ينبغي دائما تفضل ثوابت السلسلة على سلسلة حرفية عند لديك خيار.باستخدام سلسلة الثوابت ، يمكنك الحصول على مساعدة من مترجم إلى التدقيق الإملائي وبالتالي تجنب أخطاء وقت التشغيل.

تقول حرفية يتم عرضه للخطأ.ولكن لا أقول أنهم أيضا أبطأ.قارن:

// string literal
[dic objectForKey:@"a"];

// string constant
NSString *const a = @"a";
[dic objectForKey:a];

في الحالة الثانية أنا باستخدام مفاتيح مع const المؤشرات ، لذا بدلا من ذلك [a isEqualToString:b], أنا يمكن أن تفعل (a==b).تنفيذ isEqualToString: يقارن التجزئة ومن ثم يعمل الدالة C strcmp, لذلك هو أبطأ من مقارنة مؤشرات مباشرة.وهو لماذا المستمر سلاسل أفضل: فهي أسرع مقارنة وأقل عرضة للأخطاء.

إذا كنت تريد الخاص بك ثابت السلسلة أن تكون عالمية ، أن تفعل ذلك من هذا القبيل:

// header
extern NSString *const name;
// implementation
NSString *const name = @"john";

دعونا استخدام C++ منذ الهدف C هو تماما غير موجودة.

إذا كنت خبأ سلسلة إلى ثابت متغير:

const std::string mystring = "my string";

الآن عند استدعاء أساليب استخدام my_string أنت باستخدام سلسلة المستمر:

someMethod(mystring);

أو يمكنك استدعاء هذه الطرق مع سلسلة حرفية مباشرة:

someMethod("my string");

السبب يفترض أنهم نشجعكم على استخدام ثوابت السلسلة لأن الهدف C لا تفعل "تتدرب";هذا هو عندما كنت تستخدم نفس سلسلة حرفية في عدة أماكن, انها في الواقع مختلفة مؤشر لافتا إلى نسخة منفصلة من السلسلة.

القاموس مفاتيح هذا يحدث فرقا كبيرا ، لأنه إذا كنت يمكن أن نرى اثنين من المؤشرات تشير إلى نفس الشيء ، هذا هو أرخص بكثير من الاضطرار إلى القيام سلسلة كاملة المقارنة للتأكد من السلاسل ذات قيمة متساوية.

تحرير: مايك في C# سلاسل غير قابلة للتغيير ، حرفية السلاسل مع القيم متطابقة في كل نهاية لافتا في نفس قيمة سلسلة.أتصور أن هذا ينطبق على اللغات الأخرى فضلا عن أن يكون غير قابل للتغيير السلاسل.في روبي ، التي لديها قابلة للتغيير سلاسل, أنها توفر بيانات جديدة من نوع:الرموز ("فو" مقابل:فو ، حيث الأول هو سلسلة قابلة للتغيير, و هذا الأخير هو غير قابل للتغيير معرف غالبا ما تستخدم تجزئة مفاتيح).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top