美文网首页
iOS底层 -- Blcok本质之Block的类型

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

作者: happy神悦 | 来源:发表于2020-09-09 09:20 被阅读0次

    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");
    });
    

    相关文章

      网友评论

          本文标题:iOS底层 -- Blcok本质之Block的类型

          本文链接:https://www.haomeiwen.com/subject/fsylektx.html