黑马程序员-OC语言-block

——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(两个下划线)


快捷键
黑马程序员-OC语言-block_第1张图片

 <#returnType#>(^<#blockName#>)(<#parameterTypes#>) = ^(<#parameters#>) {
            <#statements#>
        };

关于block的几点思考:
block作为函数参数,也可以作为函数返回值
block用来保存一段代码,可以在恰当的时候取出来调用。
block对象是一个C级别的语法和运行机制,它与标准的C函数相似,不同之处在于它除了有可执行的代码以外,还包括堆、栈内存绑定的变量,因此,block包含着一组状态数据,这些数据在程序执行时,对程序产生影响

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

你可能感兴趣的:(黑马程序员-OC语言-block)