iOS线程开发之--BLOCK & GCD(Grand Central Dispatch)

GCD是apple在iOS 4.0之后引入的新多线程方法,它是基于C语言的扩展,

GCD是在内核级提供多线程管理的,效率较高。

GCD的关键之一是队列,系统提供了一些预定义的队列,其中包括主线程队列(该队列保证在主线程上运行),你也可以定义自己的队列。

GCD队列是严格的FIFO方式工作的,代码的开始顺序与加入队列的顺序相同。(在多核心系统上,代码块的完成顺序不一定是FIFO的。但是在目前单核的iPhone上不必在意)。

GCD的另一关键是引入了block,类似于其它语言的匿名表达式。block可以为变量赋值,可以当作参数传递给函数或方法 ,当然也可以执行。

block可以接受参数也可以返回值。block以^定义。形式上类似于以*定义的函数指针。

//声明block,变量名loggerBlock,无参数无返回
void (^loggerBlock)(void)
为该block变量定义代码
loggerBlock = ^{ NSLog(@"I’m just glad they didn’t call it a lambda"); };

执行该block

loggerBlock();  

可以看到block很类似于c时的函数指针。不过block可以以inline方式嵌入代码。同时block可以访问上下文中的变量,缺省时block会对访问的变量进行copy,而不

影响原变量的值。当然可以通过在变量前加 __block修饰符来允许直接改变访问变量。

// 定义可改变变量
__block int a = 0; 
 
// 定义block代码来改变本地变量
void (^sillyBlock)(void) = ^{ a = 47; }; 
 
// block执行前的值
NSLog(@"a == %d", a); // outputs "a == 0" 

// 执行
sillyBlock(); 
 
// 变量被改变
NSLog(@"a == %d", a); // outputs "a == 47" 

当然Block本身在iOS 4.0以后的API中扮演着举足轻重的角色,很多新增的API都可以接受BLOCK作为参数。

比如,在数据容器中支持Block来进行自定义判断:

[someArray indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        if ([[(someObj *)obj someAttr] isEqualToString:someStr ]) {
            *stop = YES;
            return YES;
        }
通过BLOCK在遍历元素过程中直接进行判断比较,找出容器中相应值的位置。




 下面看一下线程相关的函数

当有代码需要在线程中执行时,可以用dispatch_async函数,该函数接受2个参数:队列和block。队列可以是系统预定义队列,也可以是用户自定义的。而block的威力

则体现在此,可以直接编写代码,上下文一目了然。

- (IBAction)doWork:(id)sender { 
    NSDate *startTime = [NSDate date]; 
    dispatch_async(dispatch_get_global_queue(0, 0), ^{ 
        //执行计算。。。。 
        NSDate *endTime = [NSDate date]; 
        NSLog(@"Completed in %f seconds",  
              [endTime timeIntervalSinceDate:startTime]); 
    }); 
} 

此处队列是用dispatch_get_global_queue(0,0)获得,前一个参数指定队列优先级,有DISPATCH_QUEUE_PRIORITY_HIGH , DISPATCH_QUEUE_PRIORITY_LOW, DISPATCH_QUEUE_PRIORITY_DEFAULT (即0),后一个参数未使用,请设为0。

当需要在主线程上执行代码 时,只需要用dispatch_get_main_queue()得到队列并作为dispatch_async()的第一个参数即可。

- (IBAction)doWork:(id)sender { 
    NSDate *startTime = [NSDate date]; 
    dispatch_async(dispatch_get_global_queue(0, 0), ^{ 
        //执行计算。。。。 
        //在主线程上更新UI
        dispatch_async(dispatch_get_main_queue(), ^{ 
        resultsTextView.text = resultsSummary; 
        }); 
        NSDate *endTime = [NSDate date]; 
        NSLog(@"Completed in %f seconds",  
              [endTime timeIntervalSinceDate:startTime]); 
    }); 
} 


 


 


 


 

你可能感兴趣的:(iOS线程开发之--BLOCK & GCD(Grand Central Dispatch))