ARC模式下的Block

前面三章都是在MRC模式下对Block进行了一系列分析,这章将讨论ARC模式下Block有什么不一样的?

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        int a = 10;
        void(^block) (void) = ^{
            NSLog(@"%d", a);
        };
        NSLog(@"%@", block);

        NSLog(@"%@", ^{NSLog(@"%d", a);});
    }
    return 0;
}

// 打印会发现,第一个打印的block竟然在堆区,而第二打印的block在栈区
// <__NSMallocBlock__: 0x100431750>
// <__NSStackBlock__: 0x7ffeefbff4c0>

为什么在MRC模式下,上面代码中的block在栈区,而到了ARC模式下却在堆区,那是因为在ARC模式下有些API内部会对Block进行copy,下面情况会自动对Block进行copy:

- (Block)get_block {
    int index = 6;
    return ^{NSLog(@"index = %d", index);};
}

- (void) autoCopyToHeap {
    // 1、Block作为右值
    int num = 10;
    Block blk1 = ^{
        NSLog(@"num = %d", num);
    };
    NSLog(@"<1>%@", blk1);

    // 2、Block作为方法/函数返回值
    NSLog(@"<2>%@", [self get_block]);

    // 3、调用GCD API时,内部会copy Block
    NSLog(@"执行blk3前num的内存地址:%p", &num);
    __weak Block blk3 = ^{
        NSLog(@"执行blk3<时>num的内存地址:%p", &num);
    };
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), blk3);

    // 4、Cocoa框架的方法且方法名含有usingBlock/block
    NSLog(@"执行blk4前num的内存地址:%p", &num);
    __weak void (^blk4)(NSTimer *timer) = ^(NSTimer *timer) {
        NSLog(@"执行blk4<时>num的内存地址:%p", &num);
    };
    [[NSTimer timerWithTimeInterval:1 repeats:NO block:blk4] fire];
}

results matching ""

    No results matching ""