سؤال

لقد كنت أحاول استخدام كتل C الموضوعية لأول مرة لأنني استمتعت حقًا باستخدام عمليات الإغلاق بلغات مثل Python و Haskell.

لقد واجهت مشكلة ، لكنني آمل أن يتمكن شخص ما من المساعدة.

فيما يلي نسخة أبسط من المشكلة التي أواجهها.

typedef void(^BlockType)(NSString *string);

- (void)testWithtarget:(id)target action:(SEL)action
{
    BlockType block = ^(NSString *string) {
        [target performSelector:action withObject:data];
    };

    block(@"Test String"); // Succeeds

    [self performSelector:@selector(doBlock:) withObject:block afterDelay:5.0f];
}

- (void)doBlock:(BlockType)block
{
    block(@"Test String 2"); // Causes EXC_BAD_ACCESS crash
}

لذلك يبدو أن هناك نوعًا من مشكلة إدارة الذاكرة التي لا تتفاجئني ولكن ليس لدي المعرفة لرؤية الحل. ربما ما أحاول قد لا يكون ممكنًا.

مهتم برؤية ما يعتقده الآخرون :)

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

المحلول

لا يتم الاحتفاظ بالكتلة ، لأنه موجود فقط على المكدس. تحتاج إلى نسخه إذا كنت تريد استخدامه خارج نطاق المكدس الحالي (أي لأنك تستخدم afterDelay:).

- (void)testWithtarget:(id)target action:(SEL)action
{
    BlockType block = ^(NSString *string) {
        [target performSelector:action withObject:data];
    };

    block(@"Test String"); // Succeeds

    [self performSelector:@selector(doBlock:) withObject:[block copy] afterDelay:5.0f];
}

- (void)doBlock:(BlockType)block
{
    block(@"Test String 2");
    [block release];
}

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

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