سؤال

لقد سمعت الآن من عدة مصادر (Stackoverflow.com، Cocoa-Dev، الوثائق، المدونات، إلخ) أنها "مخطئة" لاستخدام الملائمين والإعدادات (FOO، SETFOO :) في أساليب INITE و Deallec. أنا أفهم أن هناك إمكانية عن بعد من مربكة الكائنات الأخرى التي تتم مراقبة الممتلكات إذا قمت بذلك. (يتم إعطاء مثال بسيط هنا)

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

وقت تشغيل الهدف الجديد - C (واحد على جهاز iPhone ووقت التشغيل 64 بت في 10.5) يتيح لك إعلان الخصائص بدون إعلان إيفار المقابلة. على سبيل المثال، سوف تجميع الفئة التالية بشكل جيد على 10.5 أو للحصول على iPhone (الجهاز، وليس محاكي):

@interface Foo : NSObject { }

  @property (retain) id someObject;

@end

@implementation Foo

  @synthesize someObject;

@end

إن فهم أن ما سبق هو فئة موضوعية سارية المفعول تماما، دعنا نقول أنني قررت كتابة مهيأة، ولأغراض إدارة الذاكرة، طريقة Deallec (نظرا لأن GC غير متوفر على iPhone). كل ما قرأته عن التهيئة والموهز سوف يقودني إلى كتابة الطريقة التالية:

- (id) init {
  if (self = [super init]) {
    //initialize the value of someObject to nil
    [self setSomeObject:nil];
  }
  return self;
}

- (void) dealloc {
  //setting someObject to nil will release the previous value
  [self setSomeObject:nil];
  [super dealloc];
}

ومع ذلك، وفقا للوثائق والرأي الشعبي، هذا هو "خطأ". لذلك أسئلتي هي:

  1. كيف من المفترض أن تهيئة Snobject دون استخدام الملحق؟ قد تقول أن المترجم (أو وقت التشغيل أو أيا كان) سيضمن أن Snobject تم تعيينه بالفعل على Nil، لكنني أعتقد أنه سيكون سلوكا غير صحيح الاعتماد عليه. وجود خلفية لائقة في ج، لقد رأيت عددا عادلا من الأخطاء بسبب عدم تهيئة المتغيرات بشكل صحيح، وهذا يبدو مختلفا قليلا.
  2. كيف يمكنني الافراج عن Snobject إذا لم يكن من المفترض أن أستخدم الملحق في طريقة Deallec؟

إذا كانت الإجابة على أي من هذه من هذه "لا يمكنك"، فماذا يمكن أن تكون سيئة لاستخدام الملاءمة في أساليب INIT و Deallec؟

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

المحلول

أفهم أن السلوك 10.5 الحالي الذي يتم بموجبه عدم إمكانية الوصول إلى شركة Ivars توليفها مباشرة من قبل Apple لتكون علة؛ يجب أن تكون قادرا على الوصول إليها مباشرة، ولكن لا أستطيع ذلك.

وبالتالي، يجب أن تكون قادرا على القيام به:

someObject = nil;

بدلا من

self.someObject = nil;

في غضون ذلك، فإن استخدام الملحق مباشرة هو السبيل الوحيد للقيام بذلك دون توفير IVAR صريح.

تحديث: تم إصلاح هذا الخطأ؛ يمكنك الآن القيام به someObject = nil بخير.

نصائح أخرى

تحرير (13 فبراير 2013): كما لوحظ في تعليقي أدناه، وخاصة منذ إضافة القوس، لقد غيرت رأيي في هذا. قبل القوس، رأيت الكثير من الأخطاء التي تسبب الأعطال بسبب تعيينات IVAR غير صحيحة في init. وبعد IMO، لا سيما العمل مع فرق صغار، والمشاكل النادرة مع استخدام الملحقات في init تفوقت بسبب الأخطاء السائبة من Ivar الوصول. نظرا لأن القوس قد تم القضاء على هذه الأنواع من الأخطاء، والأخطاء النادرة ولكن ممكنة التي تستخدم الملحق في init يمكن أن يسبب أكثر أهمية، ولذا فقد تحولت إلى دعم الاستخدام المباشر للآفات في init و dealloc, وفقط في تلك الأماكن؛ مسافات في كل مكان آخر من الممكن (من الواضح أنك لا تستطيع استخدام الملحقات داخل الملحق نفسه ....)


الإجابة قبل القوس

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

-dealloc هي مكالمة أكثر صرامة. لدي ميل طبيعي لاستخدام مسافرين هناك (بحيث يتم استخدامها في كل مكان)، ولكن يمكن أن يسبب الصداع بسبب KVO (أو حتى nsnotifications إذا قمت بنشر إشعار تغيير في Server الخاص بك). ومع ذلك، في حين أنني لا أستخدم مسافات -dealloc, ، أنا أعتبر أنها قابلة للنقاش للغاية وأبل غير متناسقة للغاية حول هذا الموضوع (نحن نعرف أنهم يتصلون setView: في uiviewcontroller -dealloc على سبيل المثال).

في أي حال، أود أن أقول إن الاستخدام الذي تسبب فيه الاستغلال في الملاعب تسبب 100x بصق الإفراط في الاستخدام. أخطأ دائما نحو استخدامها إلا عندما يكون هناك سبب قوي لعدم.

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