سؤال

سؤال غبي، ولكن لماذا نحتاج إلى استخدام "الاحتفاظ" عند الإعلان عن عقار؟ لا يتم الاحتفاظ به على أي حال عند تعيين شيء ما؟

بالنظر إلى هذا المثال، يبدو أنه يتم الاحتفاظ به كائن تلقائيا عند alloc'ed، فما هي النقطة؟

#import "Fraction.h"
#import <stdio.h>

int main( int argc, const char *argv[] ) {
    Fraction *frac1 = [[Fraction alloc] init];
    Fraction *frac2 = [[Fraction alloc] init];

    // print current counts
    printf( "Fraction 1 retain count: %i\n", [frac1 retainCount] );
    printf( "Fraction 2 retain count: %i\n", [frac2 retainCount] );

    // increment them
    [frac1 retain]; // 2
    [frac1 retain]; // 3
    [frac2 retain]; // 2

    // print current counts
    printf( "Fraction 1 retain count: %i\n", [frac1 retainCount] );
    printf( "Fraction 2 retain count: %i\n", [frac2 retainCount] );

    // decrement
    [frac1 release]; // 2
    [frac2 release]; // 1

    // print current counts
    printf( "Fraction 1 retain count: %i\n", [frac1 retainCount] );
    printf( "Fraction 2 retain count: %i\n", [frac2 retainCount] );

    // release them until they dealloc themselves
    [frac1 release]; // 1
    [frac1 release]; // 0
    [frac2 release]; // 0

■ الإخراج

الكسر 1 الاحتفاظ عدد: 1

الكسر 2 الاحتفاظ عدد: 1

الكسر 1 الاحتفاظ عدد: 3

الكسر 2 الاحتفاظ عدد: 2

الكسر 1 الاحتفاظ عدد: 2

الكسر 2 الاحتفاظ عدد: 1

الكسر الكامل

الكسر الكامل


هذا يقودني للجنون!

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

المحلول

السلوك الافتراضي للعقار هو تعيين، وليس الاحتفاظ. هذه ليست هي نفس السلوك. إذا كانت الممتلكات الخاصة بك لنوع بيانات بدائي، مثل INT، فستكون تعيين صحيحة للاستخدام. ومع ذلك، إذا قمت بتحديد (الاحتفاظ) ونقاط العقار إلى مؤشر كائن مثل NSOBJECT * كائن، يتم تعيين المؤشر عنوان ذاكرة الكائن ويتم زيادة عدد الاحتفاظ بها من قبل واحد. إذا كان برنامجك يتكون من أي شيء أكثر من وظيفة رئيسية وحيدة، فمن الصعب رؤية الغرض. ومع ذلك، افترض أن صفك لديه هذه الطريقة:

-(void)setMyArrayWithString:(NSString *)s{
    myArray = [NSArray arrayWithObject:s];
    }

لنفترض أنه يتم تعريف myarray على أنه nsarray * myarray ويحتوي على بيان property (الاحتفاظ) المناسب (الاحتفاظ). كل شيء يعمل بشكل جيد حتى تعود الأسلوب. وذلك لأن الكائن الذي تم إرجاعه من NSArray هو كائن AutoreLeased. إذا لم نحتفظ به، فسيتم إصداره من قبل NSAUTORELEASSPOOL ونحن لن نكون قادرين على استخدامه (وسنحصل على أخطاء سيئة وانتهاكات وصول سيئة). لإصلاح هذا يمكننا القيام بأحد شيئين:

-(void)setMyArrayWithString:(NSString *)s{
    self.myArray = [NSArray arrayWithObject:s];
// OR
    myArray = [[NSArray arrayWithObject:s] retain];    
}

يستخدم الحل الأول Self.Myarray للاستفادة من تعريف Roperty. يعين هذا الرمز ثم يحتفظ بالكائن حتى لا نخسره عند إرجاع الوظيفة. يحدد الحل الثاني مؤشر NSARRAY * MYARRIY يدويا ثم يحتفظ يدويا كائن NSArray يدويا. وفي كلتا الحالتين سيقوم NSAUTORELEASEPOOL بإصدار الكائن في نهاية الوظيفة، ومع ذلك لن يتم إلغاؤه لأننا لا يزال لدينا الاحتفاظ بنا من إبقاء عليه في وقت سابق على قيد الحياة.

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