iOS~Block 笔记

2018-06-20  本文已影响7人  派大星的博客

推荐文章
深入研究Block捕获外部变量和__block实现原理
Automatic Reference Counting


研究工具:clang

clang -rewrite-objc main.m

1、被捕获的局部变量在Block中不能被改变

⚠️ 全局变量和静态变量是可以被改变的,因为作用域更广。


屏幕快照 2019-01-22 下午4.16.33.png

2019-01-22 16:15:41.489808+0800 OCDemo[23367:2877052] Block外 global_i = 2,static_global_j = 2,static_k = 2,val = 2
2019-01-22 16:15:41.490085+0800 OCDemo[23367:2877052] Block中 global_i = 3,static_global_j = 3,static_k = 3,val = 1
Program ended with exit code: 0

原因是:作为非对象的局部变量被捕获的是一份copy值,而不是reference地址,不能改变其值。

⚠️ NSMutableArray、NSMutableString等是可以被改变的。

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    NSMutableArray *ayy = [[NSMutableArray alloc] initWithCapacity:10];
    int val = 1;
    void (^myBlock)(void) = ^{
        [ayy addObject: [NSNumber numberWithInteger:1]];
        NSLog(@"ayy BLock中 = %@",ayy);
        NSLog(@"val BLock中 = %d",val);

    };
    [ayy addObject: [NSNumber numberWithInteger:2]];
    [ayy addObject: [NSNumber numberWithInteger:3]];
    NSLog(@"ayy  %@", ayy);
    myBlock();

}

对于对象变量来说

对于声明为__block的外部对象,在block内部会进行retain,以至于在block环境内能安全的引用外部对象。

对于非对象变量来说

屏幕快照 2019-01-22 下午6.21.02.png

2、Block分类

自己的理解:初始化的时候isa都是_NSConcreteStackBlock,具体运行时根据不通情况变成_NSConcreteGlobalBlock或者_NSConcreteMallocBlock。

_NSConcreteStackBlock _NSConcreteGlobalBlock _NSConcreteMallocBlock

3、Block 的循环引用

image.png

Resolving Strong Reference Cycles for Closures

Swift版:[Defining a Capture List]

[unowned self, weak delegate = self.delegate!]

weak:对应生命周期更短的
unowned: 对应生命周期更长的、非nil

lazy var someClosure: (Int, String) -> String = {
    [unowned self, weak delegate = self.delegate!] (index: Int, stringToProcess: String) -> String in
    // closure body goes here
}
image.png

Objective-C版

__weak __typeof(self) weakSelf = self

4、Block 和 函数指针 的理解

image.png
上一篇 下一篇

猜你喜欢

热点阅读