程序开发iOS点点滴滴iOS学习笔记

理解block(块)

2015-07-28  本文已影响207人  我叫大大虾米

block的结构

block结构图block结构图
return_type (^block_name)(paratemters)

block的基本用法

int additional = 5;
int (^addBlock)(int a, int b) = ^(int a, int b){
    return a + b+ addition;
}

默认情况下,为block所捕获的变量,是不可以在块里修改的(需要加__block)

NSArray *array = @[@0, @1, @2, @3, @4, @5];

__block int count = 0;
   
[array enumerateObjectsUsingBlock:^(NSNumber *number, NSUInteger idx, BOOL *stop) {
       
       if ([number compare:@2] == NSOrderedAscending) {
           
           count ++;
       }
   }];
   
//    count = 2;

块总能修改实例变量,所以在声明时无需加__block

在定义blcok的时候,所占内存分配的栈中的,这就是说,块只在定义他的那个范围内有效

一下代码就很危险

void (^block)();
    
if (count == 2) {
    
    block = ^{
        
        NSLog(@"Block A");
        
    };
}else{
    
     block = ^{
        
        NSLog(@"Block B");

}

block();

首先栈内存是分配是有编译器分配和释放的,以上代码中if和else中的block被分配到栈内存中(这两个块只能保证在对应的if或else语句范围内有效),如果编译器把分配给block的内存给覆写掉,那么程序就会崩溃。
注意:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来讲,释放工作有程序员控制,容易产生memory Leak。
为解决以上问题,我们可以给block对象发送copy消息,把block从栈复制到堆上。

void (^block)();
 
if (count == 2) {
 
     [block = ^{
         
         NSLog(@"Block A");
         
     } copy];
}else{
 
     [block  =^{
     
      NSLog(@"Block B");
        
     } copy];

}

block();

全局块

可以把块定义为全局变量,在文件级别上使用。全局块可以声明到全局内存中,而不需要在每次用到得时候于栈中创建。另外全局块的copy是个空操作,因为全局块绝不可能为系统所回收。

block一般有三种,NSConcreteGlobal, NSConcreteStack, NSConcreteMalloc。
block是可以访问block外部的变量的。
NSConcreteGlobal: 就像一个全局函数一样,从头到尾待在那,始终是可用的。当Block中没有引用外部变量时,block为global类型的。
NSConcreteStack: 保存在栈中的block,block执行完后内存会被释放掉。当block引用了外部变量时,block为stack类型的。
NSConcreteMallock: 保存在堆中的block,block为引用记数为0时,内存会被释放掉。当block执行copy时,block会从栈中复制到堆中。
以上都针对非ARC环境而言,如果在ARC环境下,引用外部变量的block会自动保存在堆中,无需copy。

待续。。。

block的理解http://answerhuang.duapp.com/index.php/2013/09/07/objective-c-blocks-syntax/#carousel-generic-38

上一篇下一篇

猜你喜欢

热点阅读