天天看点

iOS学习之block

Block是带有自动变量的匿名函数。

匿名函数顾名思义就是不带名字的函数,在C语言中不允许这样的方法存在,而在OC中的Block则可以用指针来直接调用一个函数,但虽说如此我们还是需要知道指针的名称。

自动变量在Block中的具体表现就是截获自动变量,

int b = 0;
    void (^blo)() = ^{
        NSLog(@"Input:b=%d",b);
    };
    b = 3;
    blo();           

结果输出0,虽然我们在调用blo之前改变了b的值,但是输出的还是Block编译时候b的值,所以截获瞬间自动变量就是:在Block中会保存变量的值,而不会随变量的值的改变而改变。

int b = 0;
    void (^blo)() = ^{
        b = 3;
    };           

上面代码编译出错,编译器提示的大概就是不能在Block中改变变量的值。因为在Block中截获了变量的瞬间值以后就不能再改变变量的值,如果想要在Block中改变变量的值,那么我们只需要在变量声明的时候加上__Block修饰符,像这样:

__block int b = 0;
    void (^blo)() = ^{
        b = 3;
    };           

下面这样只是对截获的变量进行操作,而没有进行赋值,是可行的,

NSMutableArray *array = [[NSMutableArray alloc]init];
    void (^blo)() = ^{
        [array addObject:@"Obj"];
    };           

所以对于截获变量,可以进行操作而不可以进行赋值。但是需要注意的是在Block中不支持对C语言数组进行操作。

//block 定义

^ NSString *(NSString *a,NSString *b){
        return a;
    };

/*
“^”符号表示这是一个Block;
NSString *表示返回值。
(NSString a,NSString b)这个括号中是Block的参数,语法和C语言类似。 
*/

//可以省略Block的返回值,像下面这样写
^ (NSString *a,NSString *b){
        return a;
    };

//不带参数列表的可以写成下面的形式

^ {
        NSLog(@"我没有参数列表");
    };
 或

 ^void(void) {
        NSLog(@"我没有参数列表");
    };           

block 声明及赋值:

int (^Blo)(NSString *s1,NSString *s2);

    Blo = ^(NSString *s1,NSString *s2){
        return 1;
    };           

声明定义和使用:

typedef void(^Blo)(NSString *s1,UIColor *c);

-(void)func:(Blo)BlockPra{

    BlockPra(@"Str",[UIColor redColor]);

}

[self func:^(NSString *s1, UIColor *c) {
        NSLog(@"%@",s1);
        self.view.backgroundColor = c;
    }];