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

Objective-C编程 - 关于Block的几点

时间:2016-11-19 02:28:59      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:范围   enum   bool   快速   返回   取数   object   elf   使用   

1. 首先,我们快速过一下,什么是Block?

Block是一段代码,它在OC中以^开头,可以有返回值,和参数列表,但就是没有名字。

所以,你可以把它认为是匿名函数。

事实上,它和Swift中的闭包(Closure)是一样的。

或者,学过.NET的童鞋知道委托吧,它和委托也差不多概念。

都是可以在一个方法中传入它,作为参数的方法。

 

无参无返回值的Block:

[MyObject myMethodParam1: xx param2: ^{

  ...

}];

有参有返回值的Block:

[MyObject myMethodParam1: xx param2: ^BOOL(id param1, id param2) {

  ...

}];

 

好了,说了那么多,我们来看个例子:

myDict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
    NSLog(@"Key - %@: Value - %@", key, value);
    if ([@"END" isEqualToString:key]) {
        *stop = YES;
    }
}];

上面这段代码枚举一个字典的键值对,知道遇到END键值退出循环,否则枚举所有的键值对。

 

2. 在Block中我们可不可以使用Block范围以外声明的变量呢?

答案是可以的,但是它是只读的,你如果要修改这个变量,会编译错误。

我们还是来看上面那段代码的例子,在循环中,我们增加了一个外部变量,想要让Block提早结束

BOOL stopEarly = NO;
double stopValue = 100.2;
[myDict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
    NSLog(@"Key - %@: Value - %@", key, value);
    if ([@"END" isEqualToString:key] || [value doubleValue] == stopValue) {
        *stop = YES;
        stopEarly = YES; // 这段代码编译会出错!!
    }
}];

上面的代码stopValue变量的Block内读取没有任何问题,但是当我们企图在Block内修改stopEarly变量的值时,编译出错了!

 

那么如果,我们执意要修改Block外面的变量,是不是可以呢?

答案是可以的。

我们要使用__block关键字,原理上是通过使用该关键字,我们可以把block外的变量从栈中移到堆中,这样就可以在Block内部使用了。

当Block结束时,变量又回到栈中。

还是上面的代码,我们作下修改,如下:

__block BOOL stopEarly = NO;
double stopValue = 100.2;
[myDict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
    NSLog(@"Key - %@: Value - %@", key, value);
    if ([@"END" isEqualToString:key] || [value doubleValue] == stopValue) {
        *stop = YES;
        stopEarly = YES; 
    }
}];

if (stopEarly)
    NSLog(@"Block提前终止了!");

 

3. 当我们向Block内的对象发送消息时,系统会创建一个指向该对象的强指针

该强指针会一直保留到Block超出自己的范围,不存在。

 

4. Block数组

property (nonatomic, strong) NSMutableArray *blockArray;

...
- (void) someMethod {
    [self.blockArray addObject:^{
        ...
    }];
}

// 获取数组中的block并调用
void (^doit)(void) = self.blockArray[0];
doit();

 

Objective-C编程 - 关于Block的几点

标签:范围   enum   bool   快速   返回   取数   object   elf   使用   

原文地址:http://www.cnblogs.com/davidgu/p/6079496.html

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