سؤال

أحاول فهم الكتل. أحصل على كيفية استخدامها بشكل طبيعي ، عند نقلها مباشرة إلى طريقة. أنا مهتم الآن بأخذ كتلة ، وتخزينها (على سبيل المثال) في متغير مثيل وأدعوها لاحقًا.

يجعل دليل البرمجة الكتل يبدو وكأنه يمكنني القيام بذلك ، باستخدام block_copy / الاحتفاظ بنسخ الكتلة بعيدًا ، لكن عندما أحاول تشغيله ، أعطل برنامجي.

- (void) setupStoredBlock
{
    int salt = 42;
    m_storedBlock = ^(int incoming){ return 2 + incoming + salt; };
    [m_storedBlock retain];
}

أحاول أن أسميها لاحقًا:

- (void) runStoredBlock
{
    int outputValue = m_storedBlock(5);
    NSLog(@"When we ran our stored blockwe got back: %d", outputValue);
    [m_storedBlock release];
}

أي شخص لديه أي رؤى؟ (أو ، هل هناك شيء لا أحصل عليه مع الكتل؟)

شكرا جزيلا لك!

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

المحلول

سترغب في القيام بذلك بدلاً من ذلك:

- (void) setupStoredBlock
{
    int salt = 42;
    m_storedBlock = Block_copy(^(int incoming){ return 2 + incoming + salt; });
}

نصائح أخرى

انسخ كتلة عندما تريد أن تبقى. Autorelease أو إطلاقه عندما تمر به. احتفظ به إذا كنت بحاجة إلى طريق طويل لتهجئة /* NOP */.

@interface Foo : FooSuper {}
@property(copy) int (^storedBlock)(int);
@end

@implementation Foo
@synthesize storedBlock = mStoredBlock;

- (void)setupStoredBlock {
    self.storedBlock = ^{/*...*/};
    // or: mStoredBlock = [^{/*...*/} copy];
    // but this simple implementation violates the atomicity contract
}

- (void)runStoredBlock {
    int result = self.storedBlock(5);
    NSLog(@"%s: result = %d", __func__, result);
}
@end

• مثل جميع المتغيرات المحلية ، توجد كتلة غير قاسية على المكدس وستظهر من المكدس ، مثل أي متغير محلي آخر لم يتم الإعلان عنه ثابتًا.

• block_copy () ينسخ الكتلة من المكدس على الكومة ، حيث توجد جميع مثيلات malloc. ومثل كل طرق جديدة/نسخ ، تقوم block_copy () بإرجاع كائن مخصص للكومة مع عدد الاحتفاظ بـ 1. كتلة هي كائن ObjectIVEC ولكنه لا يتوافق مثل كائن عادي. لذلك ، لا ينبغي أن يكون هناك فرق بين block_release () وطريقة التحرير الهدف.

• يستخدم هذا المثال طريقة نسخ مثيل كتلة. لأن تعيين نتيجة block_copy () إلى معرف يتطلب نوعًا من النوع الذي لا أرغب في أخطائه. تتيح طريقة النسخ تعيين متغير الكتلة مباشرة إلى معرف.

 - (void) setupStoredBlock
{
    int zStackLocalVariable = 42;
    iHeapAllocatedVariable = [^int(int aMore){ return zStackLocalVariable + aMore; } copy];
}

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

• الكتلة هي كائن C موضوعية له من فئته والمعلومات المرتبطة به الأخرى التي لم أحاول استردادها بعد ، ولكن ، مثل البروتوكول والكائن وغيرها من فئات ObjectiveC المخفية ، لا تتوافق مع NSObject. مثل كل كائنات ObjectiveC ، ومع ذلك ، يجب أن تتوافق مع الاحتفاظ/إطلاق. يمتد ARC إلى الاحتفاظ بالمعادلات في كائنات الأساس الأساسية أيضًا ، وربما ، إن لم يكن الآن ، ثم في النهاية ، في مخصصات malloc/free.

• أنتظر الدافع الحقيقي لاستكشاف شامل لـ mikeash.com, ، نظرًا لأن Apple تحب أن تبقينا جميعًا على مستوى نظري مفرط الأهمية البدنية الصغيرة ، على الرغم من أن كل ما هو مهم جسدي.

كما تمت مناقشة القوس والكتل هنا

كان هناك عرض لطيف للغاية حول هذا الموضوع على WWDC الأخير (2010). وصف كيف تم تنفيذ الكتل ولماذا تحتاج إلى استخدام block_copy. يمكنك تنزيل فيلم من العرض التقديمي على:http://developer.apple.com/itunes/؟destination=adc.apple.com.4092414566يسمى الفيلم: "Advanced Objective-C و Garbage Collection"

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