zoukankan      html  css  js  c++  java
  • iOS开发Block的使用

    Block 是从 iOS4引入的,在日常开发中,会经常用到Block。特别是在多线程中,Block的用处更广泛。而且,Block不仅可以接收参数,其本身也可以作为参数,因此,Block的功能非常强大。简单介绍一些Block的使用。

    首先看一个Block的简单定义:

    BOOL (^isInputEven)(int) = ^(int input){
        if(input % 2 == 0){
            return YES;
        }else{
            return NO;
        }
    };

    这样就定义了一个Block。Block有返回值,有参数,有名称,Block是以“^”符号开始的。Block本身就是一个代码段,提前定义好,当需要的时候直接调用即可。

    使用上述定义的Block:

    NSLog(@"even = %d",isInputEven(4));

    使用非常简单。

    Block还可以使用同一作用域的变量,也就是说可以使用Block外部的变量。

    示例代码:

    void testBlock1()
    {
        float price = 1.99;
        float (^finalPrice)(int) = ^(int quantity){
            return quantity * price;
        };
        int quantity = 20;
        NSLog(@"price is %f",finalPrice(quantity));
    }

    Block finalPrice是可以使用外部的变量 price的。

    需要注意的是,在Block内部是不能修改变量值得,比如在Block内部写 price = 0.99,运行会发生崩溃。

    外部变量的变化不影响Block内部的值。举例来说:

    void testBlock2()
    {
        float price = 1.99;
        NSLog(@"first price = %p",price);
        float (^finalPrice)(int) = ^(int quantity){
            NSLog(@"second price = %p",price);
            return quantity * price;
        };
        
        price = 0.99;
        NSLog(@"third price = %p",price);
        
        int quantity = 20;
        NSLog(@"price is %f",finalPrice(quantity));
    }

    在代码块外,price的值已经改变,而且price的值改变之后才使用了代码块,但是代码块中的变量并没有受到影响,代码块中price的值仍然是1.99。

    原因,通过在不同的阶段打印price的地址可以发现,代码块中的price的地址和改变前和改变后的地址都是不一样的。也就是说,Block在声明的时候,就将用到的变量深拷贝了一份,因此,外部变量的改变不影响Block内部的变量。

    如果想实现外部变量的改变能够影响Block内部变量,可以使用__block,示例如下:

    void testBlock3()
    {
        __block float price = 1.99;
        float (^finalPrice)(int) = ^(int quantity){
            return quantity * price;
        };
        int quantity = 10;
        price = 0.99;
        NSLog(@"price is %f",finalPrice(quantity));
    }

    外部变量改变,Block内部的变量同样改变。

    在开发中,由于Block定义比较麻烦,通常会使用 typedef 处理一下,一方面写起来简便,另一方面,更符合写程序的习惯。

    示例程序如下:

    typedef int (^addOperation) (int a,int b);
    
    void testBlock4()
    {
        addOperation operation;
        operation = ^(int a,int b){
            return a + b;
        };
        NSLog(@"sum = %d",operation(3,5));
    }

    这样看起来会简单很多。

    Block可以作为方法的参数,比如数组、字典遍历时。举例如下:

    void testBlock5()
    {
        NSArray *array = @[@"a",@"b",@"c"];
        [array enumerateObjectsUsingBlock:^(id obj,NSUInteger idx,BOOL *stop){
            NSLog(@"%@",obj);
        }];
    }

    实际上,如果变量是可变类型的话,比如MutableArray,外部变量的变化是可以影响到Block内部的变量的。

    示例代码如下:

    void testBlock6()
    {
        NSMutableArray *array = [NSMutableArray array];
        [array addObject:@"abc"];
        void (^enumArray)() = ^(){
            for(NSString *string in array){
                NSLog(@"string = %@",string);
            }
        };
        [array addObject:@"def"];
        enumArray();
    }

    运行结果包括两个字符串,是 abc 和 def。

  • 相关阅读:
    Celery框架
    Tensorflow安装记录
    OpenFace的一些了解
    CentOS+Uwsgi+Nginx发布Flask开发的WebAPI
    Always On 集群监听创建失败问题
    SQL Server 安装好后 Always On群组配置
    Sql server 2016 Always On 搭建Windows集群配置
    汕头市队赛 SRM13 T3
    bzoj 1314: River过河 树套树+单调队列
    hdu 6119 …&&百度之星 T6
  • 原文地址:https://www.cnblogs.com/acBool/p/5149762.html
Copyright © 2011-2022 走看看