سؤال

إذا كان لدي شيء مثل UILabel مرتبط بملف xib، فهل أحتاج إلى إصداره عند إلغاء تخصيص طريقة العرض الخاصة بي؟السبب الذي أسأله هو أنني لا أخصصه، مما يجعلني أعتقد أنني لست بحاجة إلى إطلاقه أيضًا؟على سبيل المثال (في الرأس):

IBOutlet UILabel *lblExample;

في التنفيذ:

....
[lblExample setText:@"whatever"];
....

-(void)dealloc{
    [lblExample release];//?????????
}
هل كانت مفيدة؟

المحلول

إذا اتبعت ما يعتبر الآن أفضل الممارسات، فستتمكن من ذلك يجب خصائص منفذ التحرير، لأنه كان يجب عليك الاحتفاظ بها في مجموعة الوصول:

@interface MyController : MySuperclass {
    Control *uiElement;
}
@property (nonatomic, retain) IBOutlet Control *uiElement;
@end


@implementation MyController

@synthesize uiElement;

- (void)dealloc {
    [uiElement release];
    [super dealloc];
}
@end

وميزة هذا النهج هو أنه يجعل دلالات إدارة الذاكرة صريحة وواضحة، ويعمل باستمرار عبر جميع الأنظمة الأساسية لجميع ملفات nib.

ملحوظة:تنطبق التعليقات التالية فقط على نظام التشغيل iOS قبل الإصدار 3.0.مع الإصدار 3.0 والإصدارات الأحدث، يجب عليك بدلاً من ذلك حذف قيم الخصائص في viewDidUnload.

ومع ذلك، أحد الاعتبارات هنا هو الوقت الذي قد تتخلص فيه وحدة التحكم الخاصة بك من واجهة المستخدم الخاصة بها وتعيد تحميلها ديناميكيًا عند الطلب (على سبيل المثال، إذا كان لديك وحدة تحكم عرض تقوم بتحميل عرض من ملف nib، ولكن عند الطلب - على سبيل المثال تحت ضغط الذاكرة -- يطلقه، مع توقع إمكانية إعادة تحميله إذا كانت هناك حاجة إلى العرض مرة أخرى).في هذه الحالة، تريد التأكد من أنه عند التخلص من العرض الرئيسي، فإنك تتخلى أيضًا عن ملكية أي منافذ أخرى بحيث يمكن إلغاء تخصيصها أيضًا.بالنسبة إلى UIViewController، يمكنك التعامل مع هذه المشكلة عن طريق التجاوز setView: على النحو التالي:

- (void)setView:(UIView *)newView {
    if (newView == nil) {
        self.uiElement = nil;
    }
    [super setView:aView];
}

ولسوء الحظ فإن هذا يثير مشكلة أخرى.نظرًا لأن UIViewController يقوم حاليًا بتنفيذ dealloc طريقة باستخدام setView: طريقة الوصول (بدلاً من مجرد تحرير المتغير مباشرة)، self.anOutlet = nil سيتم استدعاؤه dealloc وكذلك استجابة لتحذير الذاكرة ...وهذا سوف يؤدي إلى وقوع حادث في dealloc.

العلاج هو التأكد من ضبط متغيرات المنفذ أيضًا nil في dealloc:

- (void)dealloc {
    // release outlets and set variables to nil
    [anOutlet release], anOutlet = nil;
    [super dealloc];
}

نصائح أخرى

لقد وجدت ما كنت أبحث عنه في مستندات Apple.باختصار، يمكنك إعداد الكائنات الخاصة بك كخصائص يمكنك تحريرها والاحتفاظ بها (أو @property، @synthesize فقط)، ولكن ليس عليك القيام بذلك لأشياء مثل UILabels:

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/chapter_3_section_4.html#//apple_ref/doc/uid/10000051i-CH4-SW18

ال

[anOutlet release], anOutlet = nil;

الجزء غير ضروري تمامًا إذا كنت قد كتبت setView:بشكل صحيح.

إذا لم تقم بتحريره عند إلغاء التخصيص، فسيؤدي ذلك إلى زيادة مساحة الذاكرة.

شاهد المزيد من التفاصيل هنا باستخدام الرسم البياني ObjectAlloc للأداة

يمكنك تخصيص التسمية، بمعنى ما، عن طريق إنشائها في IB.

ما يفعله IB هو إلقاء نظرة على IBOutlets الخاصة بك وكيفية تعريفها.إذا كان لديك متغير فئة يقوم IB بتعيين مرجع لبعض الكائنات، فسوف يرسل IB رسالة احتفاظ إلى هذا الكائن نيابةً عنك.

إذا كنت تستخدم الخصائص، فسوف يستخدم IB الخاصية التي لديك لتعيين القيمة ولن يحتفظ بالقيمة بشكل صريح.وبالتالي، يمكنك عادةً وضع علامة على خصائص IBOutlet على أنها تحتفظ بما يلي:

@property (nonatomic, retain) UILabel *lblExample;

وبالتالي، في حالة الأثير (باستخدام الخصائص أم لا) يجب عليك استدعاء الإصدار في صفقة التخصيص الخاصة بك.

لا يلزم تحرير أي IBOutlet يمثل عرضًا فرعيًا للعرض الرئيسي لـ Nib، لأنه سيتم إرسال رسالة الإصدار التلقائي إليه عند إنشاء الكائن.IBOutlet الوحيد الذي تحتاج إلى إصداره في صفقة التخصيص الخاصة بك هو كائنات المستوى الأعلى مثل وحدات التحكم أو NSObject الأخرى.كل هذا مذكور في مستند Apple المرتبط أعلاه.

إذا لم تقم بتعيين IBOutlet كخاصية ولكن ببساطة كمتغير مثيل، فلا يزال يتعين عليك تحريره.وذلك لأنه عند initWithNib، سيتم تخصيص الذاكرة لجميع IBOutlets.لذا فهذه إحدى الحالات الخاصة التي يجب عليك تحريرها حتى لو لم تقم بالاحتفاظ أو تخصيص أي ذاكرة في التعليمات البرمجية.

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