美文网首页
Block小探究心得

Block小探究心得

作者: xiaoliang1 | 来源:发表于2018-12-03 13:29 被阅读117次

大家经常说blcok是个结构体,每次看到都一堆编译成类c++代码。看着还是很难受。时间久了会不会自己迷糊了。一堆抽象的东西很难受。过一段时间可能忘记了。(现在的面试就有点像应试考试一样。没有实践,没有深入了解)

在我看来block就只有两种一种是在栈上的,一种在全局区。
NSConcreteGlobalBlock 全局
NSConcreteStackBlock 栈上
NSConcreteMallocBlock 堆上(现在我基本没遇到过直接可以创建,由NSConcreteStackBlock copy,产生)
既然结构体能在栈上生成么什么异议了。但是也能在堆上创建,但是NSConcreteMallocBlock在堆上的目前我还是没见到的。
(题话外,object-c 类本质是结构体,苹果却上让他直接alloc new 在堆上(既然是结构体肯定能在栈上))。
所以,今天我们直接来 NSConcreteGlobalBlock和NSConcreteStackBlock就够了。
也许大家在用Hopper找一个block函数地址非常头疼,今天看完这个你就不会头疼了。我们就是从hopper里面看block的。
先来个非常的简单的NSConcreteGlobalBlock

self.test1 = ^{

        NSLog(@"2222");
    };


    NSLog(@"block: self.test1 class is %@",[self.test1 class]);

打印结果:

2018-12-03 12:21:53.993461+0800 3333[40992:2030730] block: self.test1 class is __NSGlobalBlock__

Hopper反汇编代码:

WX20181203-123204@2x.png

我们只要看___block_literal_global就够了,点击去看看:

WX20181203-122905@2x.png

这个第三行0x0000000100001250就是代码函数地址(未在程序载入偏移后),就是代码段的偏移地址,点进去找到看看就是了


WX20181203-122709@2x.png

画红线的地方是不是上文的地方对应上了,
最后一个参数就是描述结构体,这个不用看了。
————————————————————————————
下面来看看NSConcreteStackBlock的这个有点难,
代码:

__weak typeof(self)weakself = self;
    void (^pp)(void) = ^{

        NSLog(@"1111");
        NSLog(@"%@",weakself);
    };

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

打印结果:

2018-12-03 12:37:13.176667+0800 3333[41749:2041280] block: pp class is __NSStackBlock__

为了更好演示查看别的代码和分析NSConcreteStackBlock,我选择不生成符号变文件和采用release模式来编译这样产生文件


WX20181203-124641@2x.png WX20181203-124712@2x.png

在用Hopper查看:

WX20181203-125742@2x.png

objc_initWeak 是weakself 的实现。
点0x100008008进去


WX20181203-125935@2x.png

这个玩意就是stackBlock的。被储存在sp+x10的位置
紧接着是0x100007dc0这个地址,进去你会发现这是会初始化的flag,在全局区。被存储sp+0x18的位置了,和上面只相差8字节,不截图了。从寄存器来看,他只占有2个字节。
在往下看0x100006654,储存在sp+0x20的位置,点进去才发现这是Block要调用的函数

WX20181203-130629@2x.png

是不是上下文地址对上了。

下面还有还有个地址0x100008100,是blcok的相关描述。这里不用管了。
从这个分析过程来看stackBlock是在栈区一块连续的内存,依次储存:
&NSConcreteStackBlock,
flag,
funck(blcok要调用的函数),
block相关表述结构体

至于堆上的blcok就是栈上copy过去,并不能直接创建,这里不做研究。
希望这篇文章对你找blcok要调用函数的函数地址有帮助。
好久都没时间来写东西了,现在把这东西抽空写出来了。
尊重别人的劳动成果,请不要随便拿去夸夸其谈
demo:https://github.com/LoveSVN/block-Explore

相关文章

  • Block小探究心得

    大家经常说blcok是个结构体,每次看到都一堆编译成类c++代码。看着还是很难受。时间久了会不会自己迷糊了。一堆抽...

  • iOS开发之Block原理探究

    Block概述 Block本质 Block调用 Block分类 Block循环引用 Block原理探究 Block...

  • block底层原理探究(二):内存管理

    前篇block底层原理探究(一):捕获,我们探究了block捕获外部变量的原理;如果block捕获的是对象类型的a...

  • Block 探究

    Block是OSX Snow Leopard和iOS 4引入的C语言扩充功能,是一个带有自动变量(局部变量)的匿名...

  • 探究 Block

    一、了解 Block先从一个简单的需求来说:传入两个数,并且计算这两个数的和,为此创建了这样一个block : 这...

  • Block探究

    使用clang -rewrite-objc main.m,得到编译后的c++源码,可以了解到 block也是一个结...

  • Block探究

    block的实质是什么?一共有几种block?都是什么情况下生成的? block的实质是什么? block本质上也...

  • Block探究

    block的原理是怎样?本质是什么? block本质上也是一个OC对象,block是封装了函数调用与及调用环境的O...

  • Block探究

    在我们实际的开发过程中,block的使用可以说是经常遇到到的了吧,GCD,网络请求,动画都随处可见block的影子...

  • block本质

    探究block本质fishhookHook Objective-C Block with Libffi如何使用li...

网友评论

      本文标题:Block小探究心得

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