هل تتطلب الخصائص المعلنة متغير مثيل مقابل؟
-
28-09-2019 - |
سؤال
هل تتطلب الخصائص في Objective-C 2.0 أن يتم الإعلان عن متغير مثيل مقابل؟ على سبيل المثال ، أنا معتاد على فعل شيء مثل هذا:
myobject.h
@interface MyObject : NSObject {
NSString *name;
}
@property (nonatomic, retain) NSString *name;
@end
myobject.m
@implementation
@synthesize name;
@end
ومع ذلك ، ماذا لو فعلت هذا بدلاً من ذلك:
myobject.h
@interface MyObject : NSObject {
}
@property (nonatomic, retain) NSString *name;
@end
هل هذا لا يزال صالحا؟ وهل يختلف بأي شكل من الأشكال عن مثالي السابق؟
المحلول
إذا كنت تستخدم وقت تشغيل Objective-C الحديث (أي إما iOS 3.x أو أكبر ، أو 64 بت من الثلج أو أكبر) فأنت تفعل ليس تحتاج إلى تحديد IVARs لخصائرك في حالات مثل هذه.
عندما انت @synthesize
العقار ، سيتم تصنيع IVAR في الواقع أيضا لك. هذا يدور حول سيناريو "الهش". يمكنك قراءة المزيد عنها الكاكاو مع الحب
نصائح أخرى
في الواجهة الخاصة بك ، يمكنك الإعلان رسميًا عن متغير مثيل بين الأقواس ، أو عبر @property
خارج الأقواس ، أو كليهما. وفي كلتا الحالتين ، يصبحون سمات الفصل. الفرق هو أنه إذا أعلن @property
, ، ثم يمكنك التنفيذ باستخدام @synthesize
, ، التي تلقائي تلقائيًا من أجلك/setter لك. يقوم Setter للرسائل التلقائية بتهيئة الأعداد الصحيحة والطفو إلى الصفر ، على سبيل المثال. إذا أعلنت متغير مثيل ، ولم تحدد مقابلة @property
, ، ثم لا يمكنك استخدام @synthesize
و يجب اكتب getter/setter الخاص بك.
يمكنك دائمًا تجاوز getter/setter المشفر تلقائيًا عن طريق تحديد خاص بك. يتم ذلك بشكل شائع مع managedObjectContext
خاصية تم تحميلها بتكاسل. وبالتالي ، تعلن managedObjectContext
كقرة ، ولكن بعد ذلك اكتب -(NSManagedObjectContext *)managedObjectContext
طريقة. أذكر أن الطريقة ، التي لها نفس اسم متغير/خاصية مثيل هي طريقة "getter".
ال @property
تتيح لك طريقة الإعلان أيضًا خيارات أخرى ، مثل retain
و readonly
, ، أي طريقة إعلان متغير مثيل لا. أساسًا، ivar
هي الطريقة القديمة ، و @property
يمتده ويجعله مربيًا/أسهل. يمكنك الرجوع إلى استخدام الذات. بادئة ، أو لا ، لا يهم طالما أن الاسم فريد من نوعه لهذا الفئة. خلاف ذلك ، إذا كان لدى الفئة الفائقة نفس اسم خاصية مثلك ، فعليك أن تقول إما مثل self.name أو super.name لتحديد الاسم الذي تتحدث عنه.
وبالتالي ، سترى أقل وأقل من الناس يعلنون ivar
S بين الأقواس ، وبدلاً من ذلك يتحول نحو مجرد تحديد @property
, ثم القيام به @synthesize
. لا يمكنك أن تفعل @synthesize
في تنفيذك دون مقابلة @property
. يعرف المزج فقط نوع السمة من @property
تخصيص. يتيح لك عبارة التوليف أيضًا إعادة تسمية الخصائص ، بحيث يمكنك الرجوع إلى خاصية باسم واحد (اختصار) داخل الكود الخاص بك ، ولكن خارج ملف .H استخدم الاسم الكامل. ومع ذلك ، مع الإكمال التلقائي الرائع الذي يتمتع به Xcode الآن ، فهذا أقل من ميزة ، لكنه لا يزال موجودًا.
آمل أن يساعد هذا في توضيح كل الالتباس والمعلومات الخاطئة التي تطفو هناك.
إنه يعمل في كلا الاتجاهين ولكن إذا لم تعلن عن ذلك في أقواس مجعد ، فلن ترى قيمها في مصحح الأخطاء في XCode.
من الوثائق:
بشكل عام ، يتطابق سلوك الخصائص في كل من أوقات التشغيل الحديثة والإرثية (انظر "إصدارات وقت التشغيل والمنصات" في دليل برمجة وقت التشغيل الهدف-C). هناك اختلاف رئيسي واحد: يدعم وقت التشغيل الحديث توليف متغير مثيل في حين أن وقت التشغيل القديم لا.
من أجل SynTheSize للعمل في وقت التشغيل القديم ، يجب عليك إما توفير متغير مثيل بنفس الاسم والنوع المتوافق مع الخاصية أو تحديد متغير مثيل موجود آخر في عبارة synthesize. مع وقت التشغيل الحديث ، إذا لم تقدم متغير مثيل ، يضيف المترجم واحدًا لك.
إذا كنت تستخدم Xcode 4.4 أو لاحقًا ، فسيقوم بإنشاء رمز توليف متغير مثيل لك.
عليك فقط أن تعلن الخصائص مثل أدناه ؛ سيقوم بإنشاء رمز تصنيع ومتغير مثيل رمز التصريح لك.
@property (nonatomic, strong) NSString *name;
سوف يولد رمز توليف كما
@synthesize name = _name;
ويمكنك الوصول إلى متغير المثيل باستخدام _name وهو مشابه لإعلان
NSString* _name
ولكن إذا أعلنت خاصية للقراءة فقط
@property (nonatomic, strong, readonly) NSString *name;
سوف يولد رمز
@synthesize name;
أو
@synthesize name = name;
لذلك يجب عليك الوصول إلى اسم متغير فوري بدون بادئة Out "_" بأي طريقة يمكنك من خلالها كتابة رمز التوليف الخاص بك ، ثم يقوم برنامج التحويل البرمجي بإنشاء رمز لك. يمكنك كتابة
@synthesize name = _name;
لغة البرمجة الهدف-C: توجيهات تنفيذ العقار
هناك اختلافات في سلوك توليف الإكسسوارات التي تعتمد على وقت التشغيل (انظر أيضًا "اختلاف وقت التشغيل"):
بالنسبة إلى أوقات التشغيل القديمة ، يجب إعلان متغيرات المثيل بالفعل في كتلة interface للفئة الحالية. إذا كان هناك متغير مثيل يحمل نفس اسم الخاصية ، وإذا كان نوعه متوافقًا مع نوع الخاصية ، فسيتم استخدامه - وإلا ، ستحصل على خطأ في المترجم.
للاطلاع على أوقات التشغيل الحديثة (انظر "إصدارات وقت التشغيل والمنصات" في دليل برمجة وقت التشغيل الهدف-C) ، يتم توليف متغيرات المثيل حسب الحاجة. إذا كان هناك متغير مثيل يحمل نفس الاسم بالفعل ، يتم استخدامه.