美文网首页iOS进阶
06.3-OC中block的copy操作

06.3-OC中block的copy操作

作者: 光强_上海 | 来源:发表于2020-06-14 22:35 被阅读0次

    block的copy操作

    ARC环境下,编译器会根据情况自动地将栈内存上的block拷贝到堆内存上,以下几种情况编译器都会自动将栈上的block拷贝到堆内存

    • block作为函数返回值
    • 将block赋值给__strong修饰的强指针对象
    • block作为Cocoa API中方法名含有usingBlock的方法参数
    • block作为GCD API的方法参数

    1、block作为函数的返回值时,代码如下:

    typedef void(^MyBlock)(void);
    
    MyBlock blockFun() {
        int a = 10;
        return ^{
            NSLog(@"%d", a); // 10
        };
    }
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // insert code here...
            MyBlock block = blockFun();
            
            // 执行block
            block();
            
            NSLog(@"%@", [block class]); // __NSMallocBlock__
        }
        return 0;
    }
    

    2、有强指针引用着block时,代码如下:

    typedef void(^MyBlock)(void);
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // insert code here...
            
            int a = 10;
            
            // 强指针block引用着^{NSLog(@"%d", a);}
            MyBlock block = ^{
                NSLog(@"%d", a); // 10
            };
            
            NSLog(@"%@", [block class]); // __NSMallocBlock__
            
            block();
            
            // 没有任何指针引用着^{NSLog(@"%d", a);}
            NSLog(@"%@", [^{
                NSLog(@"%d", a);
            } class]); // __NSStackBlock__
        }
        return 0;
    }
    

    3、block作为Cocoa API中方法名含有usingBlock的方法参数时,代码如下:

    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // insert code here...
            
            NSArray *arr = @[@"1", @"2", @"3"];
            
            [arr enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                NSLog(@"%@", obj);
            }];
        }
        return 0;
    }
    

    4、block作为GCD API的方法参数时,代码如下:

    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // insert code here...
            
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                NSLog(@"111");
            });
        }
        return 0;
    }
    

    讲解示例代码Demo地址:https://github.com/guangqiang-liu/06.3-BlockDemo3

    更多文章

    相关文章

      网友评论

        本文标题:06.3-OC中block的copy操作

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