美文网首页程序员iOS Developer互联网科技
block-__block修饰符和__block内存管理

block-__block修饰符和__block内存管理

作者: RM_乾笙 | 来源:发表于2018-07-03 17:39 被阅读52次

    __block修饰符的特点

    1.__block可以用于解决block内部无法修改auto变量值的问题
    2.__block不能修饰全局变量、静态变量(static)

    因在block的内部是无法修改外部的auto变量的,所以需要通过__block修饰符来修改外部auto变量的值,看看下面的一段代码:

    #import <Foundation/Foundation.h>
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // insert code here...
            
            __block auto int age = 10;
            void (^block)(void) = ^ {
                age = 20;
                NSLog(@"age is age:%d",age);
            };
            block();
        }
        return 0;
    }
    // 控制台输出
    2018-07-03 14:12:51.176447+0800 __block修饰符[22494:2047905] age is age:20
    Program ended with exit code: 0
    

    我们从上面main函数中可以得知,用__block修饰的auto变量,在block内部能够修改age的值,那__block在底层做了什么呢?我们来了解下,下面是clang 生成的c++源码:

    block修饰符

    通过上面代码分析,修饰符__block底层实际就是,编译器通过将__block修饰的变量包装成一个对象,通过对象去修改其属性age的值,所以有__block 修饰的age变量无age修饰的变量区别是很大的。

    __block内存管理

    #import <Foundation/Foundation.h>
    #import "RMPerson.h"
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // insert code here...
            __block RMPerson *person = [[RMPerson alloc] init];
            void (^block)(void) = ^ {
                NSLog(@"person : %@",person);
            };
            block();
        }
        return 0;
    }
    
    -----------------RMPerson.h-----------------
    #import <Foundation/Foundation.h>
    @interface RMPerson : NSObject
    @end
    
    -----------------RMPerson.m-----------------
    #import "RMPerson.h"
    @implementation RMPerson
    - (void)dealloc {
        NSLog(@"RMPerson - dealloc");
    }
    @end
    

    看看上面代码通过clange转成c++的代码,如下图


    block内存管理
    如果__block变量被copy到堆时

    1.会调用__block变量内部的copy函数
    2.copy函数内部会调用_Block_object_assign函数,_Block_object_assign函数会根据所指向对象的修饰符(__strong__weak__unsafe_unretained)做出相应的操作,形成强引用(retain)或者弱引用(注意:这里仅限于ARC时会retain,MRC时不会retain

    如果__block变量从堆上移除

    1.会调用__block变量内部的dispose函数
    2.dispose函数内部会调用_Block_object_dispose函数,_Block_object_dispose函数会自动释放指向的对象(release)


    相关文章

      网友评论

        本文标题:block-__block修饰符和__block内存管理

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