iOS - OC Block 代码块
前言
Block 是一段预先准备好的代码,可以在需要的时候执行,可以当作参数传递。Block 可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。Block 是 C 语言的,类似于一个匿名函数,它和传统的函数指针很类似,但是 Block 是 inline(内联函数)的,并且默认情况下它对局部变量是只读的。
苹果官方建议尽量多用 Block。在多线程、异步任务、集合遍历、集合排序、动画转场用的很多。
Block 语法
// Block as a local variable
returnType (^blockName)(parameterTypes) = ^returnType(parameters) {...}; // Block as a property
@property (nonatomic, copy) returnType (^blockName)(parameterTypes); // Block as a method parameter
- (void)someMethodThatTakesABlock:(returnType (^)(parameterTypes))blockName; // Block as an argument to a method call
[someObject someMethodThatTakesABlock: ^returnType (parameters) {...}]; // Block as typedef
typedef returnType (^TypeName)(parameterTypes);
TypeName blockName = ^returnType(parameters) {...};
1、Block 的使用
1.1 Block 的定义
Block 的简单定义
// 定义 Block
/*
定义了一个名叫 MySum 的 Block 对象,它带有两个 int 型参数,返回 int 型。等式右边就是 Block 的具体实现,大括号后需加分号
*/
int (^MySum)(int, int) = ^(int a, int b){ return a + b;
}; // 调用 Block
int sum = MySum(10, 12);
Block 数据类型的定义
// 定义 block 数据类型 MyBlock
typedef int (^MyBlock)(int, int); // 定义 MyBlock 的变量
MyBlock myblock; // 实现 MyBlock 的变量 1
myblock = ^(int a, int b){ return a + b;
}; // 调用 MyBlock 的变量 1
int sum = myblock(10, 12); // 实现 MyBlock 的变量 2
myblock = ^(int a, int b){ return a - b;
}; // 调用 MyBlock 的变量 2
int minus = myblock(13, 2);
1.2 Block 访问局部变量
Block 可以访问局部变量,但是不能修改,如果要修改需加关键字 __block(双下划线)。
// 这样定义时,局部变量 sum 只能读取值不能修改,编译时会报错
// int sum = 10; // 这样定义时,局部变量 sum 既可以读取值又能修改
__block int sum = 10; int (^MyBlock)(int) = ^(int a){ // 对局部变量值修改
sum ++; // 读取局部变量的值
return a * sum;
}; int result = MyBlock(5);
2、Block 的回调
2.1 Block 回调使用
// Block1.h
// block 属性变量定义
/*
要使用 copy 类型,格式:@property (nonatomic, copy) 返回值类型 (^变量名) (参数类型列表);
*/
@property (nonatomic, copy) void (^completion) (NSString *);
// 调用 block 代码段声明
- (void)useBlock;
// Block1.m
// 调用 block 代码段
- (void)useBlock {
// 设置 block 的回调值
// 判断是否设置了 block
if (self.completion != nil) {
// 设置回调值
self.completion(@"hello world");
}
}
// Block.m
#import "Block1.h"
Block1 *block = [[Block1 alloc] init];
// 设置 block 代码段
block.completion = ^(NSString *str) {
// 结果:string = @"hello world"
NSString *string = str;
};
// 调用 block 代码段
[block useBlock];
2.2 Block 回调封装
// Block2.h
// block 方法参数定义
// 类方法定义
+ (Block2 *)blockWithCompletion:(void (^) (NSString *)) completion;
// 调用 block 代码段声明
- (void)useBlock;
// Block2.m
// block 属性变量定义
// 要使用 copy 类型,格式:@property (nonatomic, copy) 返回值类型 (^变量名) (参数类型列表);
@property (nonatomic, copy) void (^completion) (NSString *);
// 调用 block 代码段
- (void)useBlock {
// 设置 block 的回调值
// 判断是否设置了 block
if (self.completion != nil) {
// 设置回调值
self.completion(@"hello world");
}
}
// 类方法实现
+ (Block2 *)blockWithCompletion:(void (^)(NSString *))completion {
Block2 *bl = [[Block2 alloc] init];
// 设置属性的值
bl.completion = completion;
return bl;
}
// Block.m
#import "Block2.h”
// 设置 block 代码段
Block2 *block = [Block2 blockWithCompletion:^(NSString *str) {
// 结果:string = @"hello world"
NSString *string = str;
}];
// 调用 block 代码段
[block useBlock];
3、Block 属性定义中为什么使用 copy 修饰
ARC 开发的时候,编译器底层对 block 做过一些优化,使用 copy 修饰可以防止出现内存泄漏。
从内存管理的角度而言,程序员需要管理的内存只有堆区的。如果用 strong 修饰,相当于强引用了一个栈区的变量。
而使用 copy 修饰,在设置数值的时候,可以把局部变量从栈区复制到堆区。
// 用 copy 修饰定义属性
@property (nonatomic, copy) void (^myTask)(); // 定义,myBlock 是保存在栈区的,出了作用域,就应该被销毁
void (^myBlock)() = ^ { NSLog(@"hello");
}; // 用属性记录
self.myTask = myBlock; // 执行
self.myTask();
4、循环引用
在 Block 中调用 self 容易产生循环引用,无法释放对象,在程序中可以使用析构方法判断是否产生了循环引用。
@implementation ViewController // 在 Block 中调用 self 容易产生循环引用
[[QWebImageManager sharedManager] downloadImage:self.urlStr completion:^(UIImage *image) {
self.image = image;
}]; @end
// 判断是否存在循环引用,无法释放时即存在循环引用
- (void)dealloc {
NSLog(@"成功退出");
}
可以使用关键字 __weak 声明一个弱变量,或者为属性指定 weak 特性。如:
@implementation ViewController // 弱引用 self,typeof(self) 等价于 ViewController
__weak typeof(self) weakSelf = self; [[QWebImageManager sharedManager] downloadImage:self.urlStr completion:^(UIImage *image) {
weakSelf.image = image;
}]; @end
iOS - OC Block 代码块的更多相关文章
- OC Block(代码块)
#import "ViewController.h" @interface ViewController () @end @implementation ViewControlle ...
- iOS:使用block代码块实现事件处理过程中的回调
block是什么,这里就不多加强调了,它的优点: 第一:执行效率高,速度快 第二:使用起来比代理简单,省却不少代码,增强代码美感 有一些小的知识点要强调一下: 第一点:它类似于一个匿名函数,也跟jav ...
- ios开发 block语句块
ios开发 block语句块 1.block 理解为匿名函数 2.block变量的定义 //定义block变量,^表示定义block //技巧:函数名左右加括号,在函数名前面在加^ void (^bl ...
- block(代码块)的介绍以及使用方法和变量之间的关系
http://blog.csdn.net/menxu_work/article/details/8762848 block(代码块)的介绍以及使用方法和变量之间的关系 block(代码块)的介绍以及使 ...
- block代码块介绍
关于block的简单介绍 什么是block? Block是C语言的一个语法特性,同时也是C语言的运行时特性,它很像C中的函数指针,因为你可以像使用函数指针一样的去使用block对象:它也很像C++中的 ...
- Block代码块中使用局部变量注意点
第一次写代码遇到报这个错,实在是想不通为什么,按常理应该是不会有问题,报错的呀??纠结了一会之后只好仔细查看报错原因咯,原来是: 当我们在block代码块中使用局部变量时,就会很容易出现如图的错误. ...
- IOS学习4——block代码块
本文转载自:iOS开发-由浅至深学习block 一.关于block 在iOS 4.0之后,block横空出世,它本身封装了一段代码并将这段代码当做变量,通过block()的方式进行回调.这不免让我们想 ...
- iOS学习之代码块(Block)
代码块(Block) (1)主要作用:将一段代码保存起来,在需要的地方调用即可. (2)全局变量在代码块中的使用: 全局变量可以在代码块中使用,同时也可以被改变,代码片段如下: ;//注意:全局变量 ...
- IOS Block代码块的定义与使用
代码块的本质是和其他的变量类似,不同的是,代码块存储的数据是一个函数体.使用代码块,你可以像调用其他标准函数一样的调用,可以传入参数,并得到返回值. 脱字符是代码块的语法标记.下图表示代码块的 ...
随机推荐
- FTP上传类
using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Net;usi ...
- NIOS II开发备忘录
大概有一年没做NIOS II的开发了,回想上一次做NIOS II还是去年做毕业设计的时候.那时候做的是基于SOPC的频率特性测试仪,我大约花了2个月的时间,从无到有的学习了NIOS II开发.学习过N ...
- symfony在模板中生成url
{{ path('homepage') }},这里的homepage是route配置文件的内容,或者叫别名.
- 什么情况下用+运算符进行字符串连接比调用StringBuffer/StringBuilder对象的append性能好
如果在编写代码的过程中大量使用+进行字符串评价还是会对性能造成比较大的影响,但是使用的个数在1000以下还是可以接受的,大于10000的话,执行时间将可能超过1s,会对性能产生较大影响.如果有大量需要 ...
- LeetCode----67. Add Binary(java)
package addBinary67;/* Given two binary strings, return their sum (also a binary string).For example ...
- 《python核心编程》读书笔记--第16章 网络编程
在进行网络编程之前,先对网络以及互联网协议做一个了解. 推荐阮一峰的博客:(感谢) http://www.ruanyifeng.com/blog/2012/05/internet_protocol_s ...
- 基于APK的Robotium登录人人网与发状态
搭建好Robotium的环境,大致就是下载安装jdk并配置环境变量,下载并打开Eclipse,下载安装Android SDK Tools并配置环境变量,下载安装ADT插件,创建并打开Android V ...
- session和cookie的总结
cookie在客户端保持,而session在服务器端保持. 1.cookie机制: 产生:服务器通过http协议的响应头,指示浏览器产生相应的cookie信息 使用:浏览器按照一定规则通过ht ...
- Android各种获取Context方法
首先讲一讲这四个函数的区别,后面还有我对context的一些理解区别如下所示: 原文链接http://stackoverflow.com/questions/6854265/getapplicatio ...
- Python if条件语句
1. if 条件语句 if 条件: 内容1 内容2 else: 内容3 内容4 # 一个等号是赋值(=) # 两个等号是比较(==) #不等号(!=) #if 条件1 and 条件2(并且) #if ...