iOS-2 Block

block块

系列文章:

iOS Block浅浅析 -

iOS Block实现原理

iOS Block __block说明符

iOS Block存储域及循环引用


最近又翻了一遍《Objective-C高级编程》,每读一遍感觉都不一样,理解的东西印象更深了。在此做一下笔记。推荐iOS开发者细读几遍,很受益。

通过下面几点来简单介绍下Block:

Block概要

Block语法

Block类型变量

Block截获自动变量值

__block说明符

截获OC对象

Block概要

什么是Block:带有自动变量(局部变量)的匿名函数

匿名函数:没有名称的函数。

自动变量:局部变量、函数参数。

其他语言中的Block的名称

程序语言Block的名称

C+ BlockBlock

SmalltalkBlock

RubyBlock

PythonLambda

C++Lambda

JSAnonymous function

Block语法

^ 返回值类型 参数列表 表达式例:^NSString* (NSString*str) {return[str stringByAppendingString:@"======"];    };

返回值类型 参数列表可以省略;

^ 表达式例:^{NSLog(@"我是block");    };

Block类型变量

block和C语言函数相比,除了没有^和函数名称,其他都相同。

声明Block类型变量并赋值:

NSString*(^block)(NSString*) = ^NSString* (NSString*str) {return[str stringByAppendingString:@"======"];    };    block(@"haha");//block调用

Block 变量赋值:NSString*(^block1)(NSString*) = block;

也可以使用typedef来给Block变量起别名

typedefNSString* (^MyBlock)(NSString*);

使用MyBlock类型的属性

@property(nonatomic,copy) MyBlock block;

函数传递block类型参数

- (void)function:(NSString*(^)(NSString*name))block {NSString*str =NSStringFromSelector(_cmd);NSLog(@"%@",block(str));}

block 作为函数返回值

- (NSString*(^)(NSString*))function:(NSString*)firstName {return^NSString*(NSString*lastName) {return[firstName stringByAppendingString:lastName];    };}

NSString*(^block2)(NSString*) = [selffunction:@"xiao"];NSLog(@"%@",block2(@"_ming"));打印:xiao_ming

Block截获自动变量值

通过Block语法和Block类型变量,我们理解了带有自动变量值的 匿名函数中的匿名函数,而带有自动变量值究竟是什么呢?带有自动变量值在Block中表现为截获自动变量值,实现如下:

- (void)viewDidLoad {    [super viewDidLoad];intdmy =256;intval =10;constchar*fmt ="val = %d\n";void(^blk)(void) = ^{printf(fmt,val);    };    val =2;    fmt ="These value were changed. val = %d\n";    blk();}

打印:val = 10 而不是These value were changed. val = 2

在上述代码中,Block语法的表达式使用的是它之前声明的自动变量fmt和val。Block中,Block表达式截获所使用的自动变量的值,即保存该自动变量的瞬间值。因为Block表达式保存了自动变量的值,所以在执行Block语法后,即使改写Block中使用的自动变量的值也不会影响Block执行时自动变量的值。

__block说明符

在不加__block修饰符时,Block截获的是自动变量值的瞬间值,保存后就不能改写该值。

intval =1;void(^blk)(void) = ^{    val =2;};报错:Variable is notassignable(missing __block type specifier)变量不能被赋值,缺少__block

要想在Block内部改变变量的值,需要在变量前加上 __block

该变量称为__block变量。后边会说明,__block 到底做了哪些事情。

__blockintval =1;void(^blk)(void) = ^{    val =2;};

截获OC对象

NSMutableArray *array= [NSMutableArrayarray];void(^blk)(void) = ^{    [arrayaddObject:@"haha"];//array = [NSMutableArray array];编译报错,缺少__block修饰符};

赋值给截获的array对象会编译报错,但是使用截获的值却不会有任何问题。

作者:under_control

链接:https://www.jianshu.com/p/2921fdb0ff59

来源:

你可能感兴趣的:(iOS-2 Block)