Object-C : Block的实现方式
摘自:http://www.cnblogs.com/GarveyCalvin/p/4204167.html>
Date : 2015-12-4
前言:我们可以把Block当作一个闭包函数,它可以访问外部变量和局部变量,但默认是不可以修改外部变量。你可以使用它来做回调方法,比起使用代理(Delegate)会更加直观。顺带一提,苹果很多的接口(API)都使用了Block。
一、Block的基本定义
Block的基本写法(也是详细写法):
returnType (^blockName)(params) = ^returnType(params) {
// code...
};
中文再解释:返回类型 (^Block的名字)(Block的参数) = ^返回类型(Block的参数) { 这里放代码 },例:
int (^myBlock)(int num1, int num2) = ^int(int num1, int num2){
return ;
};
如果你的Block不需要返回类型和参数,那么你可以简写为:
void (^myBlock2)() = ^(){ };
或
void (^myBlock2)(void) = ^void(void){ };
返回类型或参数,没有的话可以用“void”代替。
你也可以把等于号右边,^后的()删除,即是:
void (^myBlock2)() = ^{ };
这样是不是很简洁?
你也可以先定义一个Block函数,但不写函数的实现,我们可以在后面再写具体函数的实现,像这样:
void (^myBlock2)(void);
myBlock2 = ^{ };
二、Block作为方法定义
把Block定义在方法里,与上面不同的是,Block的名字不需要在声明时写上,而是在后面,像这样:
- (void)getWtihBlock:(void (^)())block
{
// code... // 记得要调用block
block();
}
使用方法:
[self getWtihBlock:^{
NSLog(@"sdf");
}];
下面作了一个详细点的例子,并写了备注:
/**
* 追加自身字符串N次(每次复制前加一个换行\n)
*
* @param string 字符串
* @param count 追加次数
* @param stringBlock 目标Block,其中str参数为结果字符串
*/
// Block也可以定义在方法里,但是不需要定义Block的名字
// IOS开发很多的API也用到了Block,像UIView的块动画
- (void)getStrWithString:(NSString *)string
CopyCount:(int)count
resultString:(void (^)(NSString *str))stringBlock
{
NSMutableString *newString = [NSMutableString stringWithString:string];
for (NSUInteger i = ; i < count; i++) {
NSUInteger len = [string length];
NSString *insertString = [NSString stringWithFormat:@"\n%@", string];
[newString insertString:insertString atIndex:len];
}
// 调用block,传入字符串newString
stringBlock(newString);
}
用法也是一样:
BlockObject *block = [[BlockObject alloc] init];
[block getStrWithString:@"Garvey"
CopyCount:
resultString:^(NSString *str) {
// str为处理后的结果
NSLog(@"str is %@", str);
}];
有时候复杂的Block语法会令到函数的声明难以阅读,所以会经常使用typedef对Block起一个新类型。
typedef void (^ResultBlock)(NSString *str);
定义方法时就变成了:
- (void)getStrWithString2:(NSString *)string
CopyCount:(int)count
resultString:(ResultBlock)stringBlock;
让我们对比一下,使用typedef前后:
// 使用前
- (void)getStrWithString:(NSString *)string
CopyCount:(int)count
resultString:(void (^)(NSString *str))stringBlock; // 使用后
- (void)getStrWithString2:(NSString *)string
CopyCount:(int)count
resultString:(ResultBlock)stringBlock;
注意:使用方法是一样的,只不过定义变得简单了。
如果你一直在使用代理(Delegate)进行方法回调,那么你现在可以尝试使用Block了。
博文作者:GarveyCalvin
博文出处:http://www.cnblogs.com/GarveyCalvin/
本文版权归作者和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作!
Object-C : Block的实现方式的更多相关文章
- Object-C语言Block的实现方式
开场白 Block基本概念 中间态转换方法 Block编译后结果分析 Block运行时状态与编译状态对比 开场白 Object-C语言是对C语言的扩展,所以将OC源码进行编译的时候,会将OC源 ...
- openpyxl使用sheet.rows或sheet.columns报TypeError: 'generator' object is not subscriptable解决方式
解决方案: 因为新版本的openpyxl使用rows或者columns返回一个生成器所以可以使用List来解决报错问题 >>> sheet.columns[0] Traceback ...
- iOS 转换异步block为同步方式运行
使用dispatch_semaphore_t 实现 dispatch_semaphore_t sema = dispatch_semaphore_create(0); //创建信号量 __block ...
- iOS开发-Objective-C Block的实现方式
前言:我们可以把Block当作一个闭包函数,它可以访问外部变量和局部变量,但默认是不可以修改外部变量.你可以使用它来做回调方法,比起使用代理(Delegate)会更加直观.顺带一提,苹果很多的接口(A ...
- iOS中数据传值的几种方式
值传递:基本数据类型的变量之间的数据传递 //值传递不会改变变量的值 void func(int a) { a = ; } int main(int argc, const char * argv[] ...
- Oracle中 根据 file# 和 block# 找到对象
我们在10046生产的trace 文件里经常看到下面的信息. 表示系统在等待散列读取某个文件号的某个块开始的8个块. WAIT #6: nam='db file scattered read' ela ...
- iOS分享 - 对象间的通信之delegate、notificationCenter与block
在项目开发中,常常会涉及到对象之间的通信,而为了降低对象间的耦合,会采用delegate.notificationCenter.block三种方式来进行实现,对于他们的使用,也许大家都能熟练掌握,但是 ...
- 理解 block
开始:Block 简介 Block 是 iOS 4.0 和 Mac OSX 10.6 引入的一个新特性. Block 可以极大的简化代码. 他们可以帮助你减少代码, 减少对代理的依赖, 并且写出更加简 ...
- 3种方式实现KVO并进行对比
KVO KVO属于设计模式中的观察者模式,在观察者模式中,一个对象任何状态的变更都会通知另外的对改变感兴趣的对象.这些对象之间不需要知道彼此的存在,这其实是一种松耦合的设计.当某个属性变化的时候,我们 ...
随机推荐
- linux设备驱动归纳总结(四):1.进程管理的相关概念【转】
本文转载自;http://blog.chinaunix.net/uid-25014876-id-64866.html linux设备驱动归纳总结(四):1.进程管理的相关概念 xxxxxxxxxxxx ...
- 【python cookbook】【数据结构与算法】19.同时对数据做转换和换算
问题:我们需要调用一个换算函数(例如sum().min().max()),但是首先需对数据做转换或者筛选处理 解决方案:非常优雅的方法---在函数参数中使用生成器表达式 例如: # 计算平方和 num ...
- grid
- sqlite3把字段为int32(用c++的time(nullptr)获取的)的秒数显示为年月日时分秒
select id, type, msg, datetime(updateTime, 'unixepoch', 'localtime') from ServerLog
- 输入框焦点时自动清除value
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <script typ ...
- asp.net中调用javascript自定义函数的方法(包括引入JavaScript文件)总结
通常javascript代码可以与HTML标签一起直接放在前 端页面中,但如果JS代码多的话一方面不利于维护,另一方面也对搜索引擎不友好,因为页面因此而变得臃肿:所以一般有良好开发习惯的程序员都会把 ...
- SQL语句,给自己的记录
1.group by 和求和函数的使用 select className,SUM(num) as sumNum FROM test GROUP BY className 2.更新一个字段的所有值 up ...
- 关于easyui的窗口和tab页面不执行js说明
一直以来群里里面很多人反应,在用tab加载界面的时候,界面里面的js不会执行.今天GodSon在此说明一下原因. 不管是window,dailog还是tab其实质最终都是继承了panel.panel有 ...
- C# 添加.DLL 出错的解决方法
解决方法: 1. 注册组件: 运行--cmd--regsvr32 dll的绝对路径名(例如: regsvr32 C:\bin\EFGateWayOfERP.dll) 如果注 ...
- sys模块的初步认识
#!/usr/bin/python # Filename: cat.py import sys def readfile(filename): '''Print a file to the stand ...