码迷,mamicode.com
首页 > 移动开发 > 详细

ios学习之block初探

时间:2014-07-22 14:40:16      阅读:259      评论:0      收藏:0      [点我收藏+]

标签:ios   闭包   block   存储域   

1. block概念

block是ios4.0+和Mac osX 10.6以后引进的对C语言的拓展,用来实现匿名函数的特性。所谓匿名函数,也称闭包函数,即允许创建一个临时的没有指定名称的函数。最经常用作回调函数(callback)参数的值,当然也有其他用法。比如说作为一个变量值来使用,具体用法将在后面介绍。

2. block定义:

在iOS中,使用脱字符“^”来声明一个block变量,block的内容包含在“{}”中的,并且和C语言一样用“;”来表示语句的结束。具体定义如下图所示:

bubuko.com,布布扣

1?? 我们先来定义一个简单的,无返回值,无参数的block:

-(void)blockTestOne
{
    void(^blockOne)(void) = ^(void){
        NSLog(@"this is blockOne");
    };
    blockOne();
}
可以看到,上面的代码,我们是在一个函数blockTestOne里定义了一个无返回值,无参数的block,叫做blockOne,然后我们紧接着在后面调用了这个blockOne。因为我们的block没有参数,所以在写的时候还可以简写成:
-(void)blockTestOne
{
    void(^blockOne)(void) = ^{
        NSLog(@"this is blockOne");
    };
    blockOne();
}
即省略了等号后面的参数列表。
控制台输出结果:
bubuko.com,布布扣

bubuko.com,布布扣

2??接下来,我们定义一个有参数,无返回值的block:

-(void)blockTestTwo
{
    void(^blockTwo)(int) = ^(int a){
        NSLog(@"blockTwo == %d", a);
    };
    blockTwo(20);
}
在这里,我们定义了一个无返回值,参数类型为int型的block变量,名为blockTwo,然后我们调用了blockTwo,传入参数20,控制台打印结果为:
bubuko.com,布布扣

bubuko.com,布布扣

3??然后,我们再来定义一个有返回值,并且有参数的block:

- (void)blockTestThree
{
    int (^blockThree)(int) = ^(int b){
        NSLog(@"blockThree parameter == %d", b);
        return 10;
    };
    NSLog(@"%d", blockThree(20));
<h2>}</h2>
我们在这里定义了一个返回值为int型,并且参数为int型的block变量,然后block实现里面打印了他的参数,最后回返一个常量10;我们又在block打印了blockThree,并且给他传了个参数20。控制台打印结果为:

bubuko.com,布布扣
在这里需要注意的是,因为我们定义的blockThree是有返回值的,所以当在他的实现中(即等号右边大括号里),如果没有返回值return,编译器会直接给我们报错:

bubuko.com,布布扣

bubuko.com,布布扣

3. block的存储域。

看过我之前博客文章《block传值以及利用block封装一个网络请求类点击打开链接的朋友一定好奇,为什么利用block定义的属性,要用copy特性?如图:

bubuko.com,布布扣
在这里我们来分析一下block的存储域,大家就了解了。先看一段代码:
- (void)testBlock
{
    void(^blockOne)(void) = ^{
        NSLog(@"this is blockOne");
    };
    int c = 10;
    void(^blockTwo)(void) = ^(void){
        NSLog(@"this is blockTwo %d ", c);
    };
    void(^blockThree)(void) = [[blockTwo copy] autorelease];
    NSLog(@"blockOne address == %@", blockOne);
    NSLog(@"blockTwo address == %@", blockTwo);
    NSLog(@"blockThree address == %@", blockThree);
}
在上面这段代码中,我们分别定义了三个block变量,blockOne,blockTwo和blockThree,然后,我们分别打印了他们三个的地址,他们三个的区别是,blockOne实现的仅仅是打印一句话,没有使用任何外部变量(block定义以外的变量),而blockTwo实现的是打印了一句话,并写使用了一个外部变量c,而blockThree实现的是将blockTwo拷贝一分即copy一下,然后控制台打印的结果如下:
bubuko.com,布布扣

bubuko.com,布布扣
bubuko.com,布布扣
很奇怪的可以看到,这三个block分别属于三个内存区域,blockOne因为没有使用任何外部变量,他的存储区域在全局区,而blockTwo因为使用了外部变量,则一下子跑到了stack区即栈区,而blockThree因为copy了blockTwo,则变到了堆内存中。我们都知道,在全局区和堆里面存储的对象是相对安全的,但是在栈区存储的对象就相对危险,有可能在使用他的时候其对象已经被释放,造成野指针,导致程序的crash。所以,我们在使用blcok的成员变量或者属性的时候,要将其copy到堆内存中使用。

未完待续。。。还有__block的使用,记得关注哦!今天实在太晚了。。。

ios学习之block初探

标签:ios   闭包   block   存储域   

原文地址:http://blog.csdn.net/u013950854/article/details/38026849

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