block

xiaoxiao2021-02-28  109

这是看了唐巧的block的实现的感悟

NSMutableArray *array = [NSMutableArray array]; [array addObject:^{}];

这段代码什么含义呢:打印结果 是一个数组,包含了一个全局block。

Printing description of array: <__NSArrayM 0x170258b70>( <__NSGlobalBlock__: 0x10003c0b0> )

这种呢

NSMutableArray *array = [NSMutableArray array]; char b = 'B'; [array addObject:^{ printf("%cn", b); }];

数组,包含了一个堆 block。

Printing description of array: <__NSArrayM 0x170441650>( <__NSMallocBlock__: 0x1704414d0> )

arc 只有堆block 和全局block,没有栈block

要看到的话要开mrc

在build phrase 里面 把类的编译方式换了-fno-objc-arc 就可以跑 mrc了

#import "ViewController.h" @interface ViewController () @property (copy, nonatomic) void(^myBlock)(); @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; int a = 1; void (^tempBlock)() = ^() { NSLog(@"a:%d", a); }; [self setMyBlock:tempBlock]; NSLog(@"finish set");//在这断点,观察myBlock的地址 } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated];//在这断点,再观察myBlock的地址,已经变了 self.myBlock(); NSLog(@"finish run"); } @end

试出来的结果

Printing description of *(self->_myBlock).__isa: __NSMallocBlock__ Printing description of *(tempBlock).__isa: __NSStackBlock__ 后面 Printing description of *(self->_myBlock).__isa: __NSMallocBlock__

再改

@property (copy, nonatomic) void(^myBlock)(); 改成 @property (retain, nonatomic) void(^myBlock)();

结果

Printing description of tempBlock: (void (^)(...)) tempBlock = 0x000000010000e678 Printing description of *(tempBlock).__isa: __NSStackBlock__ Printing description of self->_myBlock: (void (^)(...)) _myBlock = 0x000000010000e678 Printing description of *(self->_myBlock).__isa: __NSStackBlock__ (lldb) 后面 直接挂了,超出作用域了

结论就是mrc 才有栈block 所以要用copy 复制一份出来 复制出来的已经是在堆block上了 如果用retain 就还是原来那个对象,block 超出作用域调用了就会挂掉。

arc 则都在堆block 上。没有栈block了

这里说一点,是不是没有必要用clang 去调试,打个断点,isa指向 堆还是栈还是全局block 就看出来了。

补充一个全局的block ,就是写个block的函数

#import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; AAABlock(); } void (^AAABlock)() = ^{ printf("hello");//断点打在这里 }; @end

这是结果

Printing description of : <__NSGlobalBlock__: 0x1000080d0> Printing description of __isa: __NSGlobalBlock__

所以打断点就知道这些东西是做什么的

isa = __NSGlobalBlock__ 还有地址 代码是堆的哪里 __FuncPtr (Block`AAABlock_block_invoke at ViewController.m:34) 原来是block 所在的位置 __descriptor 应该是描述信息 Printing description of __descriptor->reserved: <nil> Printing description of __descriptor->Size: (unsigned long) Size = 32 里面有大小

还参照了这篇文章

转载请注明原文地址: https://www.6miu.com/read-38109.html

最新回复(0)