美文网首页ios 基础 面试
Block的三种类型:__NSGlobalBlock,__NSS

Block的三种类型:__NSGlobalBlock,__NSS

作者: 小心韩国人 | 来源:发表于2018-08-31 16:47 被阅读101次

我们在讲block的本质的时候已经知道了,block的本质就是一个 OC 对象,那么既然它是一个 OC 对象,它就会有类型,本文就将讲解block的三种类型.
我们在讲block的三种类型之前,先了解一下程序的内存分配情况,因为不同类型的block分配的内存也不同.

  • .text段 : 也称代码段,我们写的代码都存放在这里
  • .data区 : 也称数据区,一般存放全局变量, __NSGlobalBlock存放在这里
  • 堆区 : 存放我们自己alloc出来的对象,动态分配内存,需要程序员自己申请内存,自己管理. __NSMallocBlock存放在堆区
  • 栈区 : 一般存放局部变量,不需要程序员管理,系统自动分配,自动销毁,__NSStackBlock存放在栈区
    不同block的内存分配
一: __NSGlobalBlock
  • 结论:没有访问 auto变量 的block 就是 __NSGlobalBlock
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        static int age = 10;
        void(^block)(void) = ^{
            NSLog(@"Hello, World! %d",age);
        };
        NSLog(@"%@",[block class]);
    }
    return 0;
}
控制台输出:__NSGlobalBlock__

这个很好理解,不过多解释

  • 二: __NSStackBlock
  • 结论:访问了auto变量 的block 就是 __NSStackBlock
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        int age = 10;
        void(^block)(void) = ^{
            NSLog(@"Hello, World! %d",age);
        };
        NSLog(@"%@",[block class]);
    }
    return 0;
}
控制台输出:__NSMallocBlock__

怎么打印的是__NSMallocBlock__,刚才不是说访问了auto变量就是__NSStackBlock吗?
因为这里我们使用的是ARC,在ARC环境下,Xcode会默认帮我们做很多事情,我们在Build Settings中把ARC设置成MRC,再来打印一下:

2018-08-30 17:37:09.846365+0800 block的类型[4318:3463149] __NSStackBlock__

这次打印的就是__NSStackBlock__
❓我们思考一下,__NSStackBlock在访问外部变量时,会有什么问题?

所以,为了避免出现这种情况,我们需要把block存储在堆上,__NSMallocBlock就闪亮登场了.

  • 三: __NSMallocBlock
  • 结论: 当一个__NSStackBlock调用了copy操作,返回的就是一个__NSMallocBlock
    __NSMallocBlock

❓思考:如果我们对__NSGlobalBlock 进行一次 copy操作,会发生什么变化呢?

__NSGlobalBlock copy后
‼️注意

以上都是在MRC环境下,如果是在ARC环境下,编译器会根据情况自动将栈上的block复制到堆上,比如以下几种情况:

  • block作为函数返回值时


    block作为返回值编译器会自动copy
  • 将block赋值给__strong指针时


    被强指针引用的block会自动copy
  • block作为Cocoa API方法名含有UsingBlock的方法参数时


    UsingBlock
  • block作为GCD API的方法参数时


    GCD API的方法参数

总结:

  • 1:一共有三种类型的Block.分为__NSGlobalBlock,__NSStackBlock,__NSMallocBlock.
  • 2:没有访问 auto变量 的block 就是 __NSGlobalBlock
    访问了auto变量 的block 就是 __NSStackBlock
    当一个__NSStackBlock调用了copy操作,返回的就是一个__NSMallocBlocksing
  • 3:在ARC环境下,编译器会自动把栈上的block copy到堆上

相关文章

网友评论

    本文标题:Block的三种类型:__NSGlobalBlock,__NSS

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