黑马程序员——OC中的block:代码块

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

1、block的基本概念

Block类型是一个C级别的语法和运行机制,不是OC特有。Block对象包含着一组状态数据,这些数据在程序执行时用于对行为产生影响。作为一个回调,block特别有用,因为block既包含了回调期间的代码,又包含了执行期间需要的数据。而且,block被设计为同时兼容OC、C和C++三种语言。

2、block的基本用法

用^操作符来声明一个Block变量,并指明Block述句的开始。Block的主体包含在{}内。与C语法一样,“:”指明语句的结束。

黑马程序员——OC中的block:代码块_第1张图片

1)有参无返回值

格式:

     格式:
     void (^block变量名)(参数类型及个数) = ^(形参列表){
     代码块的语;
     };

示例:

    //定义一个变量myblock2 同时进行赋值
    void (^myblock2)(int,int)=^(int a,int b){
        NSLog(@"a + b = %d", a+b);
    };
    myblock2(34,12);
    //先定义变量,再赋值
    myblock2 = ^(int x,int y){
        int m = x>y?x:y;
        NSLog(@"max = %d",m);
    };
    myblock2(34,12);

2)有参有返回值

格式:

        格式:
        返回值类型 (^变量名)(参数类型及个数) = ^(形参列表){
                代码块的语;
                return ;
        };

示例:

        //定义
        int (^myblock1)(int , int ) = ^(int x, int y){
            return x+y;
        };
        //使用block,接收返回值
        int a = myblock1(10,20);
        NSLog(@"a = %d",a);
        //给变量重新赋值
        myblock1 =^(int x, int y){
            return x*y;
        };
        a = myblock1(10,20);
        NSLog(@"a = %d",a);

3)无参有返回值(略)

4)无参无返回值

格式:

     //定义一个没有参数没有返回值的block变量,并且赋值了
     void (^block变量名)() = ^(){
     代码块的语;
     };
     //优化
     void (^block变量名)() = ^{
     代码块的语;
     };
     //block变量的使用:
     block变量名();
示例:
    //定义
    void (^myBlock4)()=^(){
        NSLog(@"XXXX");
    };
    //使用
    myBlock4();
    //优化
    void (^myBlock5)()=^{
        NSLog(@"****");
    };
    myBlock5();

3、block的typedef

利用typedef定义block类型

格式:

typedef  返回值类型  (^新别名)(参数类型列表);
示例:
        //定义一个block变量,并且赋值
        void (^myBlock)() = ^{
            NSLog(@"helloworld");
        };
        myBlock();
        //定义一个别名
        //给 没有返回值 没有参数 的block起一个别名
        //Block 是一个类型,不再是一个单纯的变量了
        typedef void (^Block)();
        Block b1;
        b1 = ^{
            NSLog(@"helloworld");
        };
        b1();

        //定义有参数\有返回值的 block类型
        //定义新的别名
        //返回值是int 有两个int类型的参数
        typedef int (^NewType1)(int ,int );
        NewType1 nt1 = ^(int a,int b){
            return a+b;
        };
        int s = nt1(12,23);
        NSLog(@"s = %d",s);
        //连续定义多个 NewType1类型的变量
        NewType1 n1,n2,n3;
        n1 = ^(int x,int y){
            return x>y?x:y;
        };

4、block访问外部变量

1)在block内部可以访问block外部的变量

在block内部可以使用block外部的变量,但是注意,这是一个新的内存空间

在block内部也可以定义和block外部同名的变量(局部变量),此时局部变量会暂时屏蔽外部变量的作用域

2)在block内部不可以修改block“外部的变量”

非局部变量会以const变量被拷贝并存储到block中,也就是说block对其是只读的。如果尝试在block内部给make变量赋值,会抛出编译器错误,block内部是只读的。而对于全局变量,则在block内部是可以被修改的。

如果在变量前加上_ _block,就不再以const的方式拷贝,允许改变值。修改之后,在block之后(包括外面)访问该变量,则取得的是修改后的值。

冻结中的非局部变量是一个常量值,这也是一种默认的安全行为——因为这可以防止在block中的代码对非局部变量做了意外的修改。

3)block有三种,即全局block,栈block,堆block。

5、block作为函数的返回值

步骤:

1)使用typedef 定义一个新的类型

    //1)使用typedef 定义一个新的类型
    typedef void (^newType)();

2)使用新类型作为函数的返回值

    //2) 用新定义的类型作为函数的返回值
    newType test(){
        //定义block变量
        newType w1 = ^{
            NSLog(@"xxxx");
            NSLog(@"helloworld");
        };
        return w1; //返回block
    }

3)定义变量接收函数返回的值(block类型)

    //3)定义block变量接收 函数返回的结果
    newType n1 = test();

4)调用block

    //4)执行block;
    n1();
定义一个有参数有返回值的新类型,代码如下
//定义一个新的类型 newType
typedef int(^newType) (int ,int );
newType test(){
    //返回一个特殊的“值”,这个值是一个有返回值,有两个参数的代码块
    return ^(int a,int b){
        return a+b;
    };
}
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        newType n2 = test();
        int s = n2(23,12);
        NSLog(@"s = %d",s);
    }
    return 0;
}

你可能感兴趣的:(OC语言基础)