IOS开发系列——Block专题【整理,部分原创】

2022-03-08 14:25:31 浏览数 (1)

Block专题

前面基本概念部分从网上文章整理,后面使用经验为原创。

1 概念简介

Block具有将临时函数体创建为表达式的优势。Apple文档中指出:

Block是符合如下要求的匿名内联的代码集:

1 、和函数一样具有一个指定类型的参数列表;

2 、有一个可以推导或声明的返回值类型;

3 、可以从它被定义的词义范围中捕捉状态;

4 、可以在需要的时候改变词义范围的状态;

5 、可以和相同的词义范围中定义的其他的Block共享更改的可能。

6 、可以在词义范围(堆栈帧)被销毁后继续共享和修改该词义范围(堆栈帧)的状态。

Block是一个自包含的小代码段,封装了用于遍历(线性遍历)或者回调,可以并发执行的任务单元。

代码块本质上是和其他变量类似。不同的是,代码块存储的数据是一个函数体。使用代码块是,你可以像调用其他标准函数一样,传入参数数,并得到返回值。

脱字符(^)是块的语法标记。按照我们熟悉的参数语法规约所定义的返回值以及块的主体(也就是可以执行的代码)。下图是如何把块变量赋值给一个变量的语法讲解:

按照调用函数的方式调用块对象变量就可以了:

int result = myBlock(4); //result是28

2 用法示例

2.1 参数是NSString*的代码块

7 void (^printBlock)(NSString *x);

8 printBlock = ^(NSString* str)

9 {

10 NSLog(@"print:%@", str);

11 };

12 printBlock(@"hello world!");

运行结果是:

print:hello world!

2.2 代码用在字符串数组排序

1 NSArray *stringArray = [NSArray arrayWithObjects:@"abc 1", @"abc 21", @"abc 12",@"abc 13",@"abc 05",nil];

2 NSComparator sortBlock = ^(id string1, id string2)

3 {

4 return [string1 compare:string2];

5 };

6 NSArray *sortArray = [stringArray sortedArrayUsingComparator:sortBlock];

7 NSLog(@"sortArray:%@", sortArray);

运行结果:

sortArray:(

"abc05",

"abc 1",

"abc12",

"abc13",

"abc 21"

)

2.3 代码块的递归调用

代码块想要递归调用,代码块变量必须是全局变量或者是静态变量,这样在程序启动的时候代码块变量就初始化了,可以递归调用。

1 static void (^ const blocks)(int) = ^(int i)

2 {

3 if (i > 0) {

4 NSLog(@"num:%d", i);

5 blocks(i - 1);

6 }

7 };

8 blocks(3);

运行打印结果:

num:3

num:2

num:1

2.4 在代码块中使用局部变量和全局变量

2.4.1 全局变量使用方式

在代码块中可以使用和改变全局变量

1 int global = 1000;

2 int main(int argc, const char * argv[])

3 {

4 @autoreleasepool {

5 void(^block)(void) = ^(void)

6 {

7 global ;

8 NSLog(@"global:%d", global);

9 };

10 block();

11 NSLog(@"global:%d", global);

12 }

13 return 0;

14 }

运行打印结果:

global:1001

global:1001

2.4.2 局部变量使用

而局部变量可以使用,但是不能改变。

1 int local = 500;

2 void(^block)(void) = ^(void)

3 {

4 local ;

5 NSLog(@"local:%d", local);

6 };

7 block();

8 NSLog(@"local:%d", local);

在代码块中改变局部变量编译不通过。怎么在代码块中改变局部变量呢?在局部变量前面加上关键字:__block

1 __block int local = 500;

2 void(^block)(void) = ^(void)

3 {

4 local ;

5 NSLog(@"local:%d", local);

6 };

7 block();

8 NSLog(@"local:%d", local);

运行结果:

local:501

local:501

3 优劣分析

3.1 优劣简介

block优势:

a.最⼤大限度地使⽤用上下⽂文变量和环境,便于参数灵活传递。

b.内存安全(避免delegate弱引⽤用可能带来的野指针问题)。

c.使⽤⽅方便,inline声明。

block的劣势:

a.容易造成内存循环引⽤;

b.如果是跨越栈帧的调⽤用,需要有copy操作(栈->堆)

c.__block带来的野指针问题。

3.2 与Delegate 比较

1 Prefer to use blocks when object is singleton as you cannot use delegationpattern. For example if you make two or three or more UIAlertViews in aUIViewController how will you able to know which UIAlerView did what. Betterway will be to display UIAlerView with their completion handlerblock.

2 If you are targeting to write call backs for several steps of a processuse Delegation. For example UIViewContoller Delegate tells viewWillLoad,viewDidLoad,viewWillAppear, viewDidAppear and keep telling untillviewDidUnLoad. If you are targeting results of a process use Blocks -Blocks aregenerally useful to tell Failure or Success for example when you attempt toauthenticate user with Game Center it tells in completion handle block[localPlayer authenticateWithCompletionHandler:^{**} either Success or Failure.

3 Prefer to use delegate pattern if an object has multiple distinct events.For example UITextField have multiple distinct events. It should tell whenshouldBeginEditing, didBedingEditing, shouldEndEditing, didEndEditing,shouldReturn etc.

4 If your call back needs some additional information from your object(viewor ViewController) delegation pattern will be the best option. for exampleUITableView data source delegate methods require number of rows, number ofsections and each cell to be returned from its owner object.

4 使用技巧

4.1 常用技巧

4.1.1 Block定义typedef

typedef void (^WVJBResponseCallback)(id responseData);

typedef void (^WVJBHandler)(id data, WVJBResponseCallback responseCallback);

5 参考链接

Objective-C语法之代码块(block)的使用

http://blog.csdn.net/totogo2010/article/details/7839061

IOS中Block简介与用法(一)

http://blog.csdn.net/enuola/article/details/8674063

IOS block 教程

http://www.cppblog.com/cokecoffe/archive/2012/05/31/176920.html

iOS深入学习(Block全面分析)

http://my.oschina.net/leejan97/blog/268536

iOS block的用法

http://www.cnblogs.com/jy578154186/archive/2012/09/30/2709130.html

0 人点赞