前言
Objective-C中的块(block),类似于JavaScript中闭包,可以作为回调函数使用。这篇文章简单的记录了我在学习块的时候的一些自身的理解
正文
什么是闭包(Closure)
闭包就是一个函数,或者一个指向函数的指针,加上这个函数执行的非局部变量。
说的通俗一点,就是闭包允许一个函数访问声明该函数运行上下文中的变量,甚至可以访问不同运行上文中的变量。
我们用脚本语言来看一下:
function funA(callback){
alert(callback());
}
function funB(){
var str = "Hello World"; // 函数funB的局部变量,函数funA的非局部变量
funA(
function(){
return str;
}
);
}
通过上面的代码我们可以看出,按常规思维来说,变量str是函数funB的局部变量,作用域只在函数funB中,函数funA是无法访问到str的。但是上述代码示例中函数funA中的callback可以访问到str,这是为什么呢,因为闭包性。
ignore : javaScript的存在闭包是因为,function里面可以再次定义function,在第二个function里面访问第一个function的变量。而第二个function是可以在其他地方被调用的(可以返回这个function,也可以把它放到其它函数的参数列表里面当参数传递)
Objective-C中的闭包
Objective-C 里面也有闭包,它是Block。 Block类似于function方法(有自己的方法体,参数),block可以在 selector 如: -(returnType) methodName:(variableType) variableName 的方法体里面定义。Block里面可以使用Objective-C方法的局部变量。Block方法可以在其他地方使用(放到其它selector的参数列表里面,用到是回调这个块);
闭包例子
//.h
typedef BOOL (^blockType) (int);
-(blockType) blockUser;
//.m
/** 调用Block(闭包)*/
-(void)callBlockCode:(BOOL (^)(int)) bVariable {
BOOL result = bVariable(1);
if(!result) {
NSLog(@"Hello Block");
}
}
/** 将Block类型在.h文件定义*/
-(blockType) blockUser {
blockType blockVariable; //block原型声明,blockType在头文件typedel定义
int flag = 0;
blockVariable = ^ (int param) {//block定义
if(flag * param) {
return YES;
}
return NO;
};
[self callBlockCode:blockVariable];
return blockVariable;
}
//main
blockType bVariable = [test blockUser];
BOOL bv = bVariable(3);
NSLog(@"Block返回结果:%i",bv);
在main中特意返回一个Block并调用,没有任何问题,也说明了在main中也是可以访问闭包定义所在的上下文的变量,如这里的flag(在@Implementation里面)
块的语法
这里用先暂用一副图来描述它使用的语法
这里int (^myBlock) (int) 是一个块变量,在块变量中的参数列表可以只是一个类型