ما هي الآلية الأساسية لتوليف IVAR في وقت التشغيل C الهدف الحديث
-
07-07-2019 - |
سؤال
تتمثل إحدى ميزات وقت تشغيل C Modern (64 بت OS X و iPhone OS) في القدرة على توليف IVARs بشكل ديناميكي دون إعلانها بشكل صريح في الفصل:
@interface MyClass : NSObject {
// NSString *name; unnecessary on modern runtimes
}
@property (retain) NSStrng *name;
@end
@implementation MyClass
@synthesize name;
@end
في جزء كبير من الكود الخاص بي ، أستخدم تطبيقات getter المخصصة من أجل تهيئة الخصائص:
- (NSString *) name {
if (!name) {
name = @"Louis";
}
return name;
}
ما سبق غير متوافق مع Ivars المترتبة لأنه يحتاج إلى الوصول إلى Ivar لم يتم إعلانه في الرأس. لأسباب مختلفة ، أرغب في تحديث عدد من الأطر الشخصية الخاصة بي لاستخدام IVARs المُصنَّعة عند المبني على أوقات التشغيل الحديثة ، يجب تعديل الكود أعلاه للعمل مع IVARs المصنفة من أجل تحقيق هذا الهدف.
في حين أن الوثائق الهدف C 2.0 تنص على أن الإمساكات التي تم تصنيعها في وقت التشغيل الحديث سوف تجمع IVAR عند الاستخدام الأول. لا يحدد آلية المستوى المنخفض المستخدمة للقيام بذلك. هل يتم ذلك بواسطة class_getinstanceVariable () ، هل القيود المفروضة على class_addivar () خففت ، هل هي وظيفة غير موثقة int هو الهدف C 2.0 وقت التشغيل؟ على الرغم من أنه يمكنني تنفيذ سعة التخزين الجانبية الخاصة بي للبيانات التي تدعم خصائصي ، إلا أنني أفضل استخدام الآلية التي تستخدمها الملحقات المصنفة.
المحلول
ذهبت ونظرت إلى الوثائق مرة أخرى الآن ، وأعتقد أنك سوء قراءة ذلك. يتم إنشاء IVARs المصنفة في وقت الترجمة ، وليس في وقت التشغيل.
بحسب ال الوثائق الهدف-C 2.0:
هناك اختلافات في السلوك الذي يعتمد على وقت التشغيل (انظر أيضًا "اختلافات وقت التشغيل"):
بالنسبة لأوقات التشغيل القديمة ، يجب أن يتم الإعلان عن متغيرات المثيلات بالفعل في كتلة interface. إذا كان هناك متغير مثيل يحمل نفس الاسم ونوع متوافق مع وجود الخاصية ، فسيتم استخدامه - وإلا ، ستحصل على خطأ في المترجم.
بالنسبة لأوقات التشغيل الحديثة ، يتم تصنيع متغيرات المثيل حسب الحاجة. إذا كان هناك متغير مثيل يحمل نفس الاسم بالفعل ، يتم استخدامه.
لذلك كل ما عليك فعله هو إعلان متغير المثيل الذي تحتاجه ، وسيعمل نفس الرمز في كلا الأوقات ...
نصائح أخرى
ما تبحث عنه هو اسم synthesized ، مثل:
@synthesize name = _name;
...
- (NSString *) name {
if (!name) {
_name = @"Louis";
}
return _name;
}
يمكنك إضافة خصائص في وقت التشغيل مع Nskeyvaluecoding بروتوكول.
[myObject setValue:@"whatever" forKey:@"foo"];