iOS底层 -- Blcok本质之Block的类型

Block有3种类型,可以通过调用class方法或者isa指针查看具体类型,最终都是继承自NSBlock类型

  • NSGlobalBlock ( _NSConcreteGlobalBlock )
  • NSStackBlock ( _NSConcreteStackBlock )
  • NSMallocBlock ( _NSConcreteMallocBlock )

一.Block对象的存储区域

Block的类型 对象的存储域
NSGlobalBlock 程序的数据区域(.data)
NSStackBlock 栈
NSMallocBlock 堆

二.判断Block的类型

Block的类型 环境
NSGlobalBlock 没有访问auto变量
NSStackBlock 访问了auto变量
NSMallocBlock NSStackBlock调用了copy

三.Block调用copy操作

Block的类型 对象的存储域 复制效果
NSGlobalBlock 程序的数据区域 什么也不做
NSStackBlock 栈 从栈复制到堆
NSMallocBlock 堆 引用计数增加

四.ARC环境下自动为Block进行copy操作的情况

1.block作为函数返回值时

typedef void(^Block)(void);

Block test() {
    int age = 10;
    return ^{
        NSLog(@"age=%d", age);
    };
}

int main(int argc, char * argv[]) {
    @autoreleasepool {
        Block block = test();
        block();
        return 0;
    }
}

2.将block赋值给__strong指针时

void (^block)(void);

void test() {
    int age = 10;
    block = ^{
        NSLog(@"age=%d", age);
    };
}

int main(int argc, char * argv[]) {
    @autoreleasepool {
        test();
        block();
        return 0;
    }
}

3.block作为Cocoa API中方法名含有usingBlock的方法参数时

NSArray *array = [[NSArray alloc] init];
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    NSLog(@"%d", idx);
}];

4.block作为GCD API的方法参数时

dispatch_async(dispatch_get_main_queue(), ^{
    NSLog(@"1111");
});
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容