iOS block 使用

iOS block 使用

例子:

[aDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
    NSLog(@“value for key %@ is %@”, key, value);
    if ([@“ENOUGH” isEqualToString:key]) {
*stop = YES; }
}];

可以使用局部变量,但是只读。
//使用局部变量stopValue
double stopValue = 53.5;
[aDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
    NSLog(@“value for key %@ is %@”, key, value);
    if ([@“ENOUGH” isEqualToString:key] || ([value doubleValue] == stopValue)) {
*stop = YES; }
}];

//只读
BOOL stoppedEarly = NO;
double stopValue = 53.5;
[aDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
    NSLog(@“value for key %@ is %@”, key, value);
    if ([@“ENOUGH” isEqualToString:key] || ([value doubleValue] == stopValue)) {
*stop = YES;
        <span style="color:#ff0000;">stoppedEarly = YES;  // ILLEGAL</span>
} }];

如果想读写,需要在变量前加 下划线__block
原因:会将变量从栈中移到堆中,block使用, 使用完复制到堆,再放回栈。
__block BOOL stoppedEarly = NO;
double stopValue = 53.5;
[aDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
    NSLog(@“value for key %@ is %@”, key, value);
    if ([@“ENOUGH” isEqualToString:key] || ([value doubleValue] == stopValue)) {
 *stop = YES;
        stoppedEarly = YES;  // this is legal now
} }];
if (stoppedEarly) NSLog(@“I stopped logging dictionary values early!”);

只要block存在,消息中每个对象都有强指针指着。

没有参数可以不写括号。如果返回值可以通过block内容推断出来,可以不写返回类型。(e,g, return [a isKindOfClass b])

block可以像对象一样被存储

@property (nonatomic,strong) NSMutableArray *myBlocks;

[self.myBlocks addObject:^{[self doSomething]}];


void (^doit)(void) = self.myBlocks[0];
doit();
这里存在一个问题。block存在数组中,一直有一个强指针指向对象self,self也有一个强指针指向block,造成 存储循环两个都无法释放。
解决这个问题需要使用弱指针。
__weak MyClass *weakSelf = self;
[self.myBlocks addObject:^{[weakSelf doSomething]}];


什么时候使用block

枚举(就像我们在上面用NSDictionary)
查看动画(我们将讨论下一个)
排序(用一个块作比较的方法)来排序(当有事情发生时,执行这个块)
错误处理程序(如果这样做时发生错误,执行此块)
完成处理程序(当您完成此操作时,执行该块)

你可能感兴趣的:(ios,block)