Block基础点总结

2016-09-06  本文已影响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的指针做强引用

上一篇 下一篇

猜你喜欢

热点阅读