美文网首页
关于block(三)----变量引用 + __block修饰

关于block(三)----变量引用 + __block修饰

作者: stonly916 | 来源:发表于2018-04-26 17:39 被阅读0次

block引用外部变量,是在block_impl_struct上创建新的变量,然后引用外部变量值或指针,但是block认为其内部引用的外部变量和外部变量是统一体,所以始终遵循一个原则(以下简称一致原则):
在进行改值操作时,必须使变量在block内外保持一致

当使用__block修饰的时候,就可以把引用的外部变量转变为结构体(在关于block(一)中有讲到),类似于OC的对象,block内引用结构体的指针,当改变外部变量时,只需要改变结构体内部成员变量的值就可以,结构体指针不会变,block内外变量结构体保持一致

代码1


    int notChange =77;

    void(^myBlock)(void) = ^() {
        printf("ss--%d\n",notChange);
    };

    myBlock();

上面的代码,notchange在block内外的地址不一样;

原因:myBlock的内部引用了notChange的值,而不是地址,相当于重新创建了个一个int内存,所以地址不一样。

代码2


    __block int h =9;   
    __block char *string = str;
    NSMutableString * string0 = [[NSMutableString alloc] initWithString:@"123"];

    void(^staBlock1)(void) = ^{
        h =13;
        string ="bbss";
        string0 = [NSMutableString stringWithString:@"1111"];
        [string0 appendString:@"456"];
        printf("%s\n",str);
    };

    staBlock1();

上面的代码:

1.基本类型h在block内改变值时,必须用__block,否则不被允许

原因:因为block内的h和block外的地址不一样,赋值就相当于在block内进行这样的操作:int local = h;local = 13;,h在block外部并没有变化,由于这里h要关联block内外,那么必须要使用__block,将外部基本类型变量转化为结构体,通过block引用结构体的指针来同时改变变量在block内部和外部的值

一致原则:因为h在block内外地址不一样,所以对block内部的变量直接赋值就违背了一致原则,导致变量内外不一致;

2.字符串的赋值,也必须要使用__block

原因:虽然这里block引用的是string的指针,这时候用指针进行赋值string = "bbss";,那么就是让string指向字符串的首地址,在改变指针的指向,不符合一致原则

3.OC对象NSMutableString修改,直接引用就可以

原因:其实OC对象进行直接赋值也是不被允许的string0 = [NSMutableString stringWithString:@"1111”];;从这里可以看出,在block内不得更改变量的指针指向,除非使用__block。但是,对对象内部的值进行更改是没有问题的,就像这段代码[string0 appendString:@"456”];

代码3


    int test =99;
    int *tt = &test;

    ^{
        //test = test + 9;
        *tt = *tt +9;
    }();

从上面代码可以看出,对test直接更改test = test + 9;违背了一致原则,所以报错了;

而使用指针tt 却是可以的,这是因为使用test指针时,block引用的会是指针tt,代码*tt = *tt + 9;只修改了指针指向的内存块内的值,并没有修改指针本身,这样block内外值都一样,在block结束后,test的值等于108,所以符合一致原则

相关文章

  • 关于block(三)----变量引用 + __block修饰

    block引用外部变量,是在block_impl_struct上创建新的变量,然后引用外部变量值或指针,但是blo...

  • Block

    Block介绍 截获变量 __block修饰符 Block的内存管理 Block的循环引用 一、Block介绍 1...

  • iOS底层-- block

    手动目录循环引用block的类Block的相关信息block本质block如何捕获外界变量?__block修饰的本...

  • iOS 面试全方位剖析 -- Block篇

    block 介绍 截获变量 __block修饰符 Block的内存管理 Block的循环引用 为什么 weakSe...

  • iOS-Block知识点整理

    block 介绍 截获变量 __block修饰符 Block的内存管理 Block的循环引用 为什么 weakSe...

  • iOS面试之Block大全

    Block Block内容如下: 关于Block 截获变量 __block修饰符 Block的内存管理 Block...

  • iOS面试之Block模块

    Block Block内容如下: 关于Block 截获变量 __block修饰符 Block的内存管理 Block...

  • Block

    一、Block本质 二、 BlocK截获变量 三、__block 修饰变量 四、Block内存管理 五、Block...

  • OC中的Block(四)

    __block修饰符的内存管理 当block在栈上时,并不会对__block变量产生强引用 当__block修饰指...

  • __block在arc和非arc下含义

    一般在block中修改变量都需要事先加__block进行修饰。在非arc中,__block修饰的变量的引用计算是不...

网友评论

      本文标题:关于block(三)----变量引用 + __block修饰

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