码迷,mamicode.com
首页 > 其他好文 > 详细

Objective-C 14 代码块Block

时间:2016-08-15 19:12:14      阅读:135      评论:0      收藏:0      [点我收藏+]

标签:

Blocks Block 代码段

Block封装了一段代码,可以在任何时候执行。它是对C语言中函数的扩展,它实际上是C语言实现的,所以它在各种以C作为基础的语言哪都是有效的,包括Objective-C、C++以及Objective-C++。

Block可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。它和传统的函数指针很类似,但是有区别:

block是内联函数的,并且默认情况下它对局部变量是只读的。

苹果官方建议尽量多用block。在多线程、异步任务、集合遍历、集合排序、动画转场用的很多。

1 定义代码块

<returntype>(^blockname)(list of arguments) = ^(arguments){body;};

编译器可以通过代码块的内容推导出返回类型,所以可以省略它。如果代码块中没有参数,也可以省略。

int (^Sum)(int, int) = ^(int a, int b){
    return a+b;
}

=号前面是代码块的定义,而等号后面是实现内容。

定义了一个名叫Sum的block对象,带有两个int型参数,返回int。=式右边是block的具体实现。

2 使用代码块

将代码块声明成了变量,所以可以像函数一样使用它Sum(2,22);这行代码中没有幂符号,这是因为只有在定义和实现代码块的时候才需要使用它,调用时则不需要。
int (^Sum)(int, int) = ^(int a, int b){
    NSLog(@"block Sum 被调用了");
          return a+b;
};
NSLog(@"调用Sum之前。");
int a = Sum(2,22);
NSLog(@"a=%i",a);
输出结果:

2016-02-25 19:14:46.709 命令行工程[924:132247] 调用Sum之前。
2016-02-25 19:14:46.710 命令行工程[924:132247] block Sum 被调用了
2016-02-25 19:14:46.710 命令行工程[924:132247] a=24

这样会固定block,只能使用Sum调用,我们可以通常使用typedef。

3 使用typedef关键字

typedef int (^MySum) (int, int);

//声明了一个block变量,类型为MySum。使用typedef可以声明无限多个block变量,方便使用。

#import <Foundation/Foundation.h>

typedef int (^MySum)(int, int);

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        MySum sum1 = ^(int a, int b) {
            return a + b ;
        };
        MySum sum2 = ^(int a, int b) {
            return a*b;
        };
        NSLog(@"调用sum1 =%i",sum1(10,10));
        NSLog(@"调用sum2 =%i",sum2(10,10));
    }
    return 0;
}
输出:
2016-02-25 19:21:22.574 命令行工程[1002:135364] 调用sum1 =20
2016-02-25 19:21:22.575 命令行工程[1002:135364] 调用sum2 =100
Program ended with exit code: 0

4 直接使用代码块 

使用block通常不需要创建一个代码块变量,而是在代码中内联代码块的内容。

NSArray *stringArray = [NSArray arrayWithObjects:@"any", @"hello", @"body",@"good",@"cool",nil];
        //升序排列
        NSArray *sortedArray = [stringArray sortedArrayUsingComparator:^(id string1, id string2){
            //NSLog(@"string1=%@,string2=%@",string1,string2);
            return [string1 compare:string2];
        }];
        NSLog(@"sortArray:%@", sortedArray);
输出结果:
2016-08-15 14:34:06.257 命令行工程[1478:103112] sortArray:(
    any,
    body,
    cool,
    good,
    hello
)

5 局部变量

Blocks可以访问局部变量,但不可以修改。(默认情况下)

#import <Foundation/Foundation.h>

typedef int (^MySum)(int, int);

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        int local  = 100;
        __block int va = 110;
        MySum sum = ^(int a, int b) {
            NSLog(@"local = %i,va = %i",local, va);
            //local++;  Variable is not assignable(misssing __block typedef  specifier)
            va++;
            return a + b +va;
        };
        NSLog(@"调用Sum之前。");
        int a = sum(10,10);
        NSLog(@"调用Sum之后。");
        NSLog(@"va = %i",va);
        NSLog(@"a=%i",a);
    }
    return 0;
}
输出:
2016-02-25 19:23:34.909 命令行工程[1028:136661] 调用Sum之前。
2016-02-25 19:23:34.910 命令行工程[1028:136661] local = 100,va = 110
2016-02-25 19:23:34.910 命令行工程[1028:136661] 调用Sum之后。
2016-02-25 19:23:34.910 命令行工程[1028:136661] va = 111
2016-02-25 19:23:34.910 命令行工程[1028:136661] a=131
Program ended with exit code: 0
由上述例子可以看出局部变量local是不可以在block中改变的,如果修改会警告??:

Variable is not assignable(misssing __block typedef  specifier)

而局部变量va是可以修改的,加上__block(两个下划线)。

有些变量无法声明为__block类型的:

没有长度可变的数组;

没有包含可变数组的结构体。

局部变量值

double a1 = 10,b = 20;
        SampleBlock sample = ^{
            return a1*b;
        };
        NSLog(@"%f",sample());
        a1 = 20;
        b = 50;
        NSLog(@"%f",sample());
结果:
2016-08-15 14:43:44.172 命令行工程[1573:107965] 200.000000
2016-08-15 14:43:44.175 命令行工程[1573:107965] 200.000000
我刚开始以为第二个会输出1000,但是不是。
这是因为变量是局部变量,代码块会在定义时复制并保存它们的状态,所以两次输出结果一样。

6 全局变量

将上面的变量改为全局变量会是怎样的结果呢?

static double a1 = 10,b = 20;
        SampleBlock sample = ^{
            return a1*b;
        };
        NSLog(@"%f",sample());
        a1 = 20;
        b = 50;
        NSLog(@"%f",sample());
结果:

2016-08-15 15:00:22.142 命令行工程[1633:113895] 200.000000
2016-08-15 15:00:22.142 命令行工程[1633:113895] 1000.000000
这说明block定义时不会复制全局变量的值。并且block可以更改全局变量的值。


Objective-C 14 代码块Block

标签:

原文地址:http://blog.csdn.net/vnanyesheshou/article/details/50682637

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!