美文网首页
Block基础点总结

Block基础点总结

作者: 轩洛 | 来源:发表于2016-09-06 23:03 被阅读0次

    1.定义

    1. Block是OC中的一种数据类型,在iOS开发中被广泛使用,是用来保存一段代码
    2. ^是Block的特有标志
    3. Block的实现代码包含在{}之间
    4. 大多情况下,以内联inline函数的方式被定义和使用
    5. Block与C语言的函数指针有些相似,但使用起来更加灵活
      5.1) 可以保存代码
      5.2) 有返回值
      5.3) 有形参

    block的定义方式:
    先写^,然后写返回值类型,接着是参数类型,参数名,然后是大括号,分号,大括号里面的代码

    //定义block
    //返回值可以自己推断出来是什么类型的
    ^int(int x,int y){
        return x + y
    };
    解释:
    ^ : block的标志:
    第一个int:返回值类型;
    int x:  第一个参数类型和参数名;
    int y:第二个参数类型和参数名;
    {}里面是我们想实现的某些功能,不能少了分号。
    

    例如:

    格式说明:
    (返回类型)(^块名称)(参数类型) = ^(参数列表){
                代码实现
    };
    //如果没有参数,等号后面参数列表的()可以省略
    
    #无返回值,无参数
    void(^demoBlock)() = ^void(){
         NSLog(@"hello world");
    }();//在此加上小括号()就是block调用
    或者
    void(^demoBlock)() = ^{
        NSLog(@"hello world");
    };
    
    #无返回值,有参数
    void (^sumBlock) (int,int) = ^(int x,int y){
           return x + y;
    };
    
    #有返回值,无参数
    NSString(^demoBlock)() = ^NSString *(){
           return @"hello world";
    };
    
    #有返回值,有参数
    int(^demoBlock)(int x,int y) = ^int(){
           return x * y;
    };
    

    2.常见相关面试题
    block可以使用在定义之前声明的局部变量:

    int i = 10;
    void(^myBlock)() = ^{
           NSLog(@"%d",i);
    };
    i = 100;//实际上并没有效果
    myBlock();
    
    #输出结果为:10
    

    注意:
    (1) 在定义Block时,会在Block中建立当前局部变量内容的副本(拷贝)
    (2) 后续再对该变量的数值进行修改,不会影响Block中的数值
    (3) 如果需要在block中保持局部变量的数值变化,需要使用__block关键字
    (4) 使用此关键字后,同样可以在Block中修改该变量的数值

    3.当做参数传递
    Block可以被当做参数直接传递:

    NSArray *array = @[@"张三",@"李四",@"尼玛",@"赵五"];
        [array enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            NSLog(@"%d %@",(int)idx,obj);
            if ([@"尼玛" isEqualToString:obj]) {
                *stop = YES;
            }
        }];
    #说明:遍历并NSLog()array中的内容,当obj为“尼玛”时停止遍历
    

    4.使用局部变量
    在被当做参数传递时,Block同样可以使用在定义之前声明的局部变量:

    int stopIndex = 1;
        NSArray *arr = @[@"张三",@"李四",@"尼玛",@"赵五"];
        [arr enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            NSLog(@"第%d项内容是%@",(int)idx,obj);
            if ([@"尼玛" isEqualToString:obj] || idx == stopIndex) {
                *stop = YES;
            }
        }];
    

    注意:默认情况下,Block外部的变量,在Block中是只读的

    BOOL flog = NO;;
        NSArray *ar = @[@"张三",@"李四",@"尼玛",@"赵五"];
        [ar enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            
            if ([@"尼玛" isEqualToString:obj] || idx == stopIndex) {
            *stop = YES;
            flog = YES; //编译错误 爆红了
          }
        }];
    

    5.__block关键字
    如果需要修改Block之外的局部变量,需要使用这个关键字

    __block BOOL flog = NO;
        NSArray *ar = @[@"张三",@"李四",@"尼玛",@"赵五"];
        [ar enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            
              if ([@"尼玛" isEqualToString:obj] || idx == stopIndex) {
            *stop = YES;
            flog = YES; //现在可以修改了!!!!
          }
        }];
    提示:无需使用__block关键字,在块代码中可以修改成员变量的数值(比较少用)
    

    6.传递对象
    对象传递进Block的方式

    NSString *stopName = @"尼玛";
        NSArray *nameArr = @[@"张三",@"李四",@"尼玛",@"赵五"];
        [nameArr enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            NSLog(@"第%d项内容是%@",(int)idx,obj);
            if ([stopName isEqualToString:obj] || idx == stopIndex) {
                *stop = YES;
            }
        }];
    

    为保证Block中代码正常运行,在stopName的指针传递Block时,Block会自动对stopName的指针做强引用

    相关文章

      网友评论

          本文标题:Block基础点总结

          本文链接:https://www.haomeiwen.com/subject/mfzcsttx.html