1、定义

(1) Block是OC中的一种数据类型,在iOS开发中被广泛使用

(2) ^是Block的特有标记

(3) Block的实现代码包含在{}之间

(4) 大多情况下,以内联inline函数的方式被定义和使用

(5) Block与C语言的函数指针有些相似,但使用起来更加灵活

例如:

void(^demoBlock)() = ^ {

NSLog(@"demo Block");

};

int(^sumBlock)(int, int) = ^(int x, int y) {

return x + y;

};

格式说明:

(返回类型)(^块名称)(参数类型) = ^(参数列表) {代码实现};

如果没有参数,等号后面参数列表的()可以省略

2、常见相关面试题

Block可以使用在定义之前声明的局部变量:

int i = 10;

void(^myBlock)() = ^{

NSLog(@"%d", i);

};

i = 100;//实际上并没效果

myBlock();

输出结果为:10

注意:

(1) 在定义Block时,会在Block中建立当前局部变量内容的副本(拷贝)

(2) 后续再对该变量的数值进行修改,不会影响Block中的数值

(3) 如果需要在block中保持局部变量的数值变化,需要使用__block关键字

(4) 使用__block关键字后,同样可以在Block中修改该变量的数值

3、当做参数传递

Block可以被当做参数直接传递:

NSArray *array = @[@"张三", @"李四", @"王五", @"赵六"];

[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

NSLog(@"第 %d 项内容是 %@", (int)idx, obj);

if ([@"王五" isEqualToString:obj]) {

*stop = YES;

}

}];

说明:遍历并NSLog() array中的内容,当obj 为"王五"时停止遍历

4、使用局部变量

在被当做参数传递时,Block同样可以使用在定义之前声明的局部变量:

int stopIndex = 1;

NSArray *array = @[@"张三", @"李四", @"王五", @"赵六"];

[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

NSLog(@"第 %d 项内容是 %@", (int)idx, obj);

if ([@"王五" isEqualToString:obj] || idx == stopIndex) {

*stop = YES;

}

}];

注意,默认情况下,Block外部的变量,在Block中是只读的

BOOL flag = NO;

[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

if ([@"王五" isEqualToString:obj] || idx == stopIndex) {

*stop = YES;

flag = YES;      // 编译错误!!!

}

}];

5__block关键字

如果要修改Block之外的局部变量需要使用__block关键字

__block BOOL flag = NO;

[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

if ([@"王五" isEqualToString:obj] || idx == stopIndex) {

*stop = YES;

flag = YES;      // 现在可以修改了!!!

}

}];

提示:无需使用__block关键字,在块代码中可以修改成员变量的数值(比较少用)

6传递对象

对象传递进Block的方式

NSString *stopName = @"王五";

NSArray *array = @[@"张三", @"李四", @"王五", @"赵六"];

[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

NSLog(@"第%d项内容是%@", (int)idx, obj);

if ([stopName isEqualToString:obj] || idx == stopIndex) {

*stop = YES;

}

}];

为保证Block中的代码正常运行,在将stopName的指针传递给Block时,Block会自动对stopName的指针做强引用

7Block在栈区工作示意图

8typedef

可以使用typedef定义一个Block的类型,便于在后续直接使用

typedef double(^MyBlock)(double, double);

MyBlock area = ^(double x, double y) {

return x * y;

};

MyBlock sum = ^(double a, double b) {

return a + b;

};

NSLog(@"%.2f", area(10.0, 20.0));

NSLog(@"%.2f", sum(10.0, 20.0));

说明:

(1) typedef是关键字用于定义类型,MyBlock是定义的Block类型

(2) area、sum分别是MyBlock类型的两个Block变量。

尽管,typedef可以简化Block的定义,但在实际开发中并不会频繁使用typedef关键字。

这是因为Block具有非常强的灵活性,尤其在以参数传递时,使用Block的目的就是为了立即使用。

官方的数组遍历方法声明如下:

而如果使用typedef,则需要:

(1) typedef void(^EnumerateBlock)(id obj, NSUInteger idx, BOOL *stop);

(2) - (void)enumerateObjectsUsingBlock:(EnumerateBlock)block;

而最终的结果却是,除了定义类型之外,EnumerateBlock并没有其他用处。

9添加到数组

既然Block是一种数据类型,那么可以将Block当做比较特殊的对象

#pragma mark 定义并添加到数组

@property (nonatomic, strong) NSMutableArray *myBlocks;

int(^sum)(int, int) = ^(int x, int y) {

return [self sum:x y:y];

};

[self.myBlocks addObject:sum];

int(^area)(int, int) = ^(int x, int y) {

return [self area:x y:y];

};

[self.myBlocks addObject:area];

#pragma mark 调用保存在数组中的Block

int(^func)(int, int) = self.myBlocks[index];

return func(x, y);

10循环引用

@property (nonatomic, strong) NSMutableArray *myBlocks;

#pragma mark 将代码改为调用self的方法

int(^sum)(int, int) = ^(int x, int y) {

return [self sum:x y:y];

};

[self.myBlocks addObject:sum];

#pragma mark 对象被释放时自动调用

- (void)dealloc

{

NSLog(@"DemoObj被释放");

}

11、解除循环引用

局部变量默认都是强引用的,离开其所在的作用域之后就会被释放。

使用__weak关键字,可以将局部变量声明为弱引用

__weak DemoObj *weakSelf = self;

在Block中引用weakSelf,则Block不会再对self做强引用

int(^sum)(int, int) = ^(int x, int y) {

return [weakSelf sum:x y:y];

};

iOS开发之Block的更多相关文章

  1. iOS 开发之Block

    iOS 开发之Block 一:什么是Block.Block的作用 UI开发和网络常见功能的实现回调,按钮事件的处理方法是回调方法. 1.     按钮事件 target action 机制. 它是将一 ...

  2. 李洪强iOS开发之Block和协议

    李洪强iOS开发之Block和协议 OC语言BLOCK和协议 一.BOLCK (一)简介 BLOCK是什么?苹果推荐的类型,效率高,在运行中保存代码.用来封装和保存代码,有点像函数,BLOCK可以在任 ...

  3. IOS开发之block应用

    非常长时间都是在学习各位大神的力作,并汲取了不少养料,在此一并谢过各位大神了. 当然了.好东西是要跟大家一起分享的,近期发现了几个很不错的个人网站,都是介绍IOS开发的.当中有唐巧.破船之长.池建强. ...

  4. ios开发之block的使用,及注意事项

    转自:http://my.oschina.net/u/1432769/blog/390401 Block作为C语言的扩展,并不是高新技术,和其他语言的闭包或lambda表达式是一回事.需要注意的是由于 ...

  5. iOS开发之block解析

    1. block的本质是一个Objective-C的对象,为什么这么说? 在Objective-C中,runtime会在执行时依据对象的isa指针的指向,来度额定这个对象的类型,也能够觉得一个对象,它 ...

  6. iOS 开发之 GCD 不同场景使用

    header{font-size:1em;padding-top:1.5em;padding-bottom:1.5em} .markdown-body{overflow:hidden} .markdo ...

  7. iOS 开发之 GCD 基础

    header{font-size:1em;padding-top:1.5em;padding-bottom:1.5em} .markdown-body{overflow:hidden} .markdo ...

  8. iOS开发之MVVM在项目中的应用

    今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...

  9. 李洪强iOS开发之RunLoop的原理和核心机制

    李洪强iOS开发之RunLoop的原理和核心机制 搞iOS之后一直没有深入研究过RunLoop,非常的惭愧.刚好前一阵子负责性能优化项目,需要利用RunLoop做性能优化和性能检测,趁着这个机会深入研 ...

随机推荐

  1. 告诉你 IOS9.0 之后的Bitcode到底是什么!!

    用Xcode 7 beta 3在真机(iOS 8.3)上运行一下工程,结果发现工程编译不过.看了下问题,报的是以下错误: ld: ‘/Users/**/Framework/SDKs/PolymerPa ...

  2. 学习笔记--jQuery基础

    学习笔记也算总结知识点,有些示例可能没有具体到元素,直接给出的语法.大家有基本理解在看可能会好些. jQuery使用前提,需要安装jQuery库 jQuery 库是一个 JavaScript 文件,您 ...

  3. java udp socket通信(仅发送)

    实现功能:客户端发送一个字符串(可以为汉字),服务器端接收并显示 服务器端程序: package udpServer; import java.io.*; import java.net.*; /** ...

  4. .Net程序员学用Oracle系列(16):访问数据库(ODP.NET)

    1..Net for Oracle 常见数据库驱动 1.1.微软提供的驱动 1.2.甲骨文提供的驱动 1.3.其它厂商提供的驱动 2.ODP.NET 常见问题分析 2.1.参数化问题 2.2.方法调用 ...

  5. WEB前端性能优化之一——网页级优化

    1.减少Http请求 http请求是指从客户端到服务器端的请求消息.其中包含对html.css.js.图片资源以及交互数据处理内容等.在前端性能网页级优化中较少http请求是非常重要的一块,每当我们提 ...

  6. Boost.Hana在visual studio 2017 rc中的残缺使用

    最新的visual studio还不支持hana,不知道vs2017正式版本出后会不会支持.等不及了,先用rc版试试吧. 1.从https://github.com/boostorg/hana下载或拉 ...

  7. iOS详解MMDrawerController抽屉效果(一)

      提前说好,本文绝对不是教你如何使用MMDrawerController这个第三方库,因为那太多人写了 ,也太简单了.这篇文章主要带你分析MMDrawerController是怎么实现抽屉效果,明白 ...

  8. 安装和配置Symfony

    为了简化创建新项目的过程,Symfony提供一个安装程序. 安装Symfony Installer 使用Symfony Installer是创建新的Symfony项目的唯一推荐方式,这个install ...

  9. BZOJ ac100题存档

    不知不觉AC100题了,放眼望去好像都是水题.在这里就做一个存档吧(特别感谢各位大神尤其是云神http://hi.baidu.com/greencloud和丽洁姐http://wjmzbmr.com/ ...

  10. bootstrap select2 参数详解

    Select2使用示例地址: https://select2.github.io/examples.html Select2参数文档说明: https://select2.github.io/opti ...