zoukankan      html  css  js  c++  java
  • block的循环引用问题1(ARC和MRC下返回block)

    1.首先是block的声明和线程安全

    * 对于没有引用外部变量的block,无论在ARC还是MRC,类型都是__NSGlobaBlock__,这种类型的block可以理解成全局的block,不需要考虑作用域,同时用copy或retain也是无效的

        MyBlock block = func();

        NSLog(@"%d", block());

        NSLog(@"%@", [block class]);

        MyBlock block2 = [block copy];

        //Copy操作对__NSGlobalBlock__类型无效

        NSLog(@"%d", block == block2); 

    打印的是123 /n __NSGlobaBlock__ /n 1, 此时的block是全局的, 拷贝无效

    #pragma mark - 不引用外部变量 ARC,MRC同样

    typedef int (^MyBlock)();

    MyBlock func(){

        return ^{

            return 123;

        };

    };

    #pragma mark - 引用外部变量 ARC可以这样(下面),

    typedef int (^MyBlock)();

    MyBlock func(){

      int a = 123;

        return ^{

            return a;

        };

    };

    此时打印的是 123 /n __NSMallocBlock__ , 说明已经拷贝到了堆区中

    MRC下回提示Returning block that lives on the local stack,因为此时引用了外部变量,他的作用域只会在声明他的函数栈内类型是__NSStackBlock__

    MRC下需要将block赋值到堆区中才可以在函数外使用block(如下)

    typedef int(^MyBlock)();
    MyBlock func()
    {
    //非ARC
    int i = 123;
    return [^{ return i; } copy];
    }

    #pragma mark - 通过输出变量的指针,验证block被拷贝之后, 他说引用的变量被赋值到了堆区中
    //非ARC
    void func()
    {
    int a = 123;
    __block int b = 123;
    NSLog(@"%@", @"=== block copy前");
    NSLog(@"&a = %p, &b = %p", &a, &b);

    void(^block)() = ^{
    NSLog(@"%@", @"=== Block");
    NSLog(@"&a = %p, &b = %p", &a, &b);
    NSLog(@"a = %d, b = %d", a, b = 456);
    };
    block = [block copy];
    block();

    NSLog(@"%@", @"=== block copy后");
    NSLog(@"&a = %p, &b = %p", &a, &b);
    NSLog(@"a = %d, b = %d", a, b);

    [block release];
    }
    输出:
    === block copy前
    &a = 0x7fff5fbff8bc, &b = 0x7fff5fbff8b0
    === Block
    &a = 0x100201048, &b = 0x100201068
    a = 123, b = 456
    === block copy后
    &a = 0x7fff5fbff8bc, &b = 0x100201068
    a = 123, b = 456
    可以看到,在Block执行中,他所引用的变量a和b都被复制到了堆上。而被标记__block的变量事实上应该说是被移动到了堆上,因此,当Block执行后,函数栈内访问b的地址会变成堆中的地址。而变量a,仍会指向函数栈内原有的变量a的空间

    参考地址:百度搜索:iOS: 非ARC下返回Block   https://www.mgenware.com/blog/?p=503

  • 相关阅读:
    handler bundle message
    php xampp xdebug phpstorm调试
    centos 5.5 安装 KVM
    结构体数组 and 结构体数组大小的内存
    char * char [ ] char string
    val text html
    PHP
    黑马程序员——java学习16(张孝祥)——反射
    黑马程序员——java学习15(毕25)——正则表达式
    黑马程序员——java学习14(毕23-24)——网络编程
  • 原文地址:https://www.cnblogs.com/guofuzhang/p/5408163.html
Copyright © 2011-2022 走看看