块的NSDictionary作为参数导致溢出

Pho*_*Luo 4 objective-c objective-c-blocks

我理解块是客观的c对象,并且在使用ARC时可以在没有Block_copy的情况下直接放在NSDictionary中. 但是我的代码出现了EXC_BAD_ACCESS错误:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self method1:^(BOOL result){
        NSLog(@"method1WithBlock finished %d", result);
    }];
}

- (void) method1:(void (^)(BOOL))finish{

    NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:^(NSData *rcb){
        finish(YES);
    }, @"success",
                          ^(NSError *error){
                              finish(NO);
                         }, @"failure",  nil];

    [self method2:dict];
}


- (void) method2:(NSDictionary *)dict{
    void (^success)(NSData *rcb) = [dict objectForKey:@"success"];
    success(nil);
}
Run Code Online (Sandbox Code Playgroud)

如果我将method1更改为this,则不会引发错误.

- (void) method1:(void (^)(BOOL))finish{
    void (^success)(NSData *)  = ^(NSData *rcb){
        finish(YES);
    };

    void (^failure)(NSError *error) = ^(NSError *error){
        finish(NO);
    };
    NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:success, @"success",
                          failure, @"failure",  nil];
    [self method2:dict];
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释为什么我必须使用自动变量来存储块之前将它们放到字典中?

我使用的是iOS SDK 6.1.

Mar*_*n R 5

根据"转换到ARC发行说明",您必须复制存储在字典中的块(强调我的):

在ARC模式下向块传递块时块"正常工作",例如在返回中.您不必再调用Block Copy. 将堆栈"向下"传递到其他执行保留的方法仍需要使用[^{} copy].arrayWithObjects:

第二种方法"偶然"工作,因为successfailure是一个 __NSGlobalBlock__而不是需要复制到堆的"基于堆栈的块".