——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
block是什么?
block 就是一段可执行的代码(代码块),它就和函数指针一样, 相当于一个可执行的函数。
block 与函数指针的区别:
C语言不支持在函数中定义函数。有了代码块, 在 OC 的函数中, 允许定义 block, 这个 block 好比一个函数。
与函数一样, block 也有四种类型:有(无)参数有(无)返回值
举例:有参数有返回值
int (^myblock)(int a, int b) = ^(int num1, int num2){
int res = num1 + num2;
return res;
};
定义block*类型*的别名
typedef void (^abc)();//由类型abc声明的变量是无参数无返回值的block 类型
返回值是block
abc (^myblock)()=^{
abc block;//由类型abc声明的变量是无参数无返回值的block 类型
block = ^{ NSLog(@"wo是定义在 一个 block 中的 block"); };
return block;
};
// 函数的颗粒化
myblock()();
//等同于
abc func = myblock();
func();
参数是block
//1.定义一个类型叫myblock, 他是一个无参数,无返回值的代码块类型
typedef void (^myblock)();
//2.定义一个函数, 参数是 myblock 类型的
void func( myblock foo )
{
//3.在函数中,myblock类型的变量是一个代码块,可以被调用
foo();
}
//4, 要调用函数,首先要准备一个myblock 类型的代码块
myblock block = ^{
NSLog(@"123");
};
//5, 调用函数func,将无参数无返回值的代码块传入
func( block );
利用block遍历C语言数组
// for 循环里面的东西(在这里是block) 就决定了如何遍历
typedef int (^myblock)(int result,int index); //有参数,无返回值
int func(char array[], int length, myblock block) {
int res=1;
for (int i = 0; i < length; i++)
{
//2.去调用block(把实参穿进去)
res=block(res,array[i]);
}
return res;
}
int main(int argc, const char * argv[]) {
@autoreleasepool
{
char array[] = {1,2,3,4,5};
//3.来调用block
myblock block=^(int result,int index)
{
result *=index;
return result;
};
//1.调用函数
int f =func(array, 5, block);
printf("%d",f);
}
return 0;
}
关于调用过程的分析
程序的入口是main函数,main函数去调用func函数,并将实际参数传进去(在这里只是传了一个block变量),走到func函数里面,func函数又会调用block,并将实际参数传进去,等待返回结果。函数运算结束后,会就将结果再返回给main函数。
block作为参数传递时,通常是直接在函数或方法的参数处写 block 的代码
func(array, 5, ^(int result,int index){result *=index; return result;};);
block访问外部变量
// 1, 定义 block 类型
typedef void (^MyBlock)( int value);
// 2, 定义函数, 将数组, 长度和 block 作为参数
void func(int array[], int length, MyBlock block)
{
for (int i = 0; i < length; i++)
{
block( array[i]);
}
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
int arr[] = {1, 2, 3, 4, 5};
__block int sum = 0;// 如果在 block 中要修改 num 的值, 就需要用 __block 修饰变量
func(arr, 5, ^(int v){
sum += v;
});
NSLog(@"数组元素和为: %d", sum);
}
return 0;
}
总结
sum在block中显然是不允许修改的
如果想访问,那就在局部变量sum前加__block(两个下划线)
<#returnType#>(^<#blockName#>)(<#parameterTypes#>) = ^(<#parameters#>) {
<#statements#>
};
关于block的几点思考:
block作为函数参数,也可以作为函数返回值
block用来保存一段代码,可以在恰当的时候取出来调用。
block对象是一个C级别的语法和运行机制,它与标准的C函数相似,不同之处在于它除了有可执行的代码以外,还包括堆、栈内存绑定的变量,因此,block包含着一组状态数据,这些数据在程序执行时,对程序产生影响
。
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-