`
stephen830
  • 浏览: 2965316 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

dispatch_queue_t初学

 
阅读更多

dispatch_queue_t初学

 

转载自 http://wsqwsq000.iteye.com/blog/1156400

 

 

1. GCD 使用后不用程序去管理线程的开闭,GCD会在系统层面上去动态检测系统状态,开闭线程

2. Dispatch Queues   单行 并行 2  FIFO  task依次放入单行queue可以实现顺序执行

3. Operation Queues 可以指定任务之间的优先级  task之间的先后依赖关系
4. __block变量是可以改变的,共享的;

示例

 

	//获得全局并发队列对象:
	dispatch_queue_t aQueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
	for (__block int i=0; i<10000; i++) {
		dispatch_async(aQueue, ^{
			NSLog(@"%i",i);
		});
	}
 

代码运行结果:

2011-07-05 17:11:38.346 ttt[41418:1803] 61
2011-07-05 17:11:38.346 ttt[41418:5f03] 1292
2011-07-05 17:11:38.348 ttt[41418:1803] 4096
2011-07-05 17:11:38.348 ttt[41418:5f03] 4954
2011-07-05 17:11:38.349 ttt[41418:1803] 5823
2011-07-05 17:11:38.349 ttt[41418:5f03] 6159
2011-07-05 17:11:38.349 ttt[41418:1803] 6575
2011-07-05 17:11:38.349 ttt[41418:5f03] 6634
2011-07-05 17:11:38.350 ttt[41418:1803] 7936
2011-07-05 17:11:38.350 ttt[41418:5f03] 8428
2011-07-05 17:11:38.351 ttt[41418:1803] 8895
2011-07-05 17:11:38.351 ttt[41418:5f03] 9364
2011-07-05 17:11:38.351 ttt[41418:1803] 9836
2011-07-05 17:11:38.351 ttt[41418:5f03] 10000
2011-07-05 17:11:38.354 ttt[41418:1803] 10000

 

 

5. 一般外部变量是copy正在运行时的外部状态

示例:

 

 

	//获得全局并发队列对象:
	dispatch_queue_t aQueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
	for (int i=0; i<10; i++) {
		dispatch_async(aQueue, ^{
			NSLog(@"%i",i);
		});
	}
 

代码运行结果:

 

2012-03-29 11:36:39.476 Test04[57035:ae03] 0

2012-03-29 11:36:39.477 Test04[57035:e103] 1

2012-03-29 11:36:39.478 Test04[57035:ae03] 2

2012-03-29 11:36:39.478 Test04[57035:e103] 3

2012-03-29 11:36:39.479 Test04[57035:ae03] 4

2012-03-29 11:36:39.483 Test04[57035:e403] 5

2012-03-29 11:36:39.483 Test04[57035:e103] 6

2012-03-29 11:36:39.485 Test04[57035:ae03] 7

2012-03-29 11:36:39.485 Test04[57035:e603] 8

2012-03-29 11:36:39.485 Test04[57035:e403] 9

 

 

6. queue可以有结束时执行的方法

示例:

 

 

//my queue结束函数
void myQueueEnd(){
	NSLog(@"my queue finished");
}

-(void)thirdMethod{
	//定义并创建1个队列
	dispatch_queue_t aQueue=dispatch_queue_create("myQuete", NULL);
	//设置内容属性
	dispatch_set_context(aQueue, @"");
	//设置队列执行结束后的调用函数
	dispatch_set_finalizer_f(aQueue, &myQueueEnd);
	for (int i=0; i<10; i++) {
		dispatch_async(aQueue, ^{
			NSLog(@"i=%i",i);
		});
	}
	//释放队列,在队列释放后执行上面函数dispatch_set_finalizer_f
	//中设置的结束函数myQueueEnd
	dispatch_release(aQueue);
}

 

执行thirdMethod方法后显示结果如下:

 

2012-03-29 11:39:20.617 Test04[57057:ae03] i=0

2012-03-29 11:39:20.623 Test04[57057:ae03] i=1

2012-03-29 11:39:20.625 Test04[57057:ae03] i=2

2012-03-29 11:39:20.626 Test04[57057:ae03] i=3

2012-03-29 11:39:20.628 Test04[57057:ae03] i=4

2012-03-29 11:39:20.629 Test04[57057:ae03] i=5

2012-03-29 11:39:20.630 Test04[57057:ae03] i=6

2012-03-29 11:39:20.631 Test04[57057:ae03] i=7

2012-03-29 11:39:20.635 Test04[57057:ae03] i=8

2012-03-29 11:39:20.636 Test04[57057:ae03] i=9

2012-03-29 11:39:20.638 Test04[57057:ae03] my queue finished


 

 

7. dispatch_sync(queue,task)会阻塞当前线程直到queue完成了你给的task,但queue要完成你给的task,因为queueFIFO的,意味着要完成之前的任务,才有机会执行你刚才给的task, 相当于当前线程等待queue里面所有任务执行完毕,所以这句话不能在当前queue的任务代码里面调用,会造成死锁。

 

-(void)fourthMethod{
	//定义并创建1个队列queue
	dispatch_queue_t aQueue=dispatch_queue_create("myQueue", NULL);
	//设置内容属性
	dispatch_set_context(aQueue, @"");
	//设置队列执行结束后调用的函数
	dispatch_set_finalizer_f(aQueue, &myQueueEnd);
	//异步方式执行队列(非组塞)
	for (int i=0; i<10; i++) {
		dispatch_async(aQueue, ^{
			NSLog(@"%i",i);
		});
		
	}
	NSLog(@"waiting");
	//同步方式执行队列(组塞)
	dispatch_sync(aQueue, ^{
		NSLog(@"wait done");
	});
	
	//释放队列,在队列释放后执行上面函数dispatch_set_finalizer_f
	//中设置的结束函数muQueueEnd
	dispatch_release(aQueue);
}
 

执行fourthMethod方法后显示结果如下:

 

2012-04-09 13:45:04.960 Test04[1622:9203] waiting

2012-04-09 13:45:04.961 Test04[1622:e003] 0

2012-04-09 13:45:04.962 Test04[1622:e003] 1

2012-04-09 13:45:04.964 Test04[1622:e003] 2

2012-04-09 13:45:04.968 Test04[1622:e003] 3

2012-04-09 13:45:04.970 Test04[1622:e003] 4

2012-04-09 13:45:04.971 Test04[1622:e003] 5

2012-04-09 13:45:04.973 Test04[1622:e003] 6

2012-04-09 13:45:04.976 Test04[1622:e003] 7

2012-04-09 13:45:04.977 Test04[1622:e003] 8

2012-04-09 13:45:04.979 Test04[1622:e003] 9

2012-04-09 13:45:04.979 Test04[1622:9203] wait done

2012-04-09 13:45:04.980 Test04[1622:e003] my queue finished

 

 

8.dispatch_sync只能对一个queue等待,group可以等好几个queue执行完.

 

-(void)fifthMethod{
	//创建1个队列组
	dispatch_group_t queueGroup=dispatch_group_create();
	//创建1个队列:aQueue
	dispatch_queue_t aQueue=dispatch_queue_create("aQueue", NULL);
	//创建另一个队列:bQueue
	dispatch_queue_t bQueue=dispatch_queue_create("bQueue", NULL);
	//在队列组中执行队列a
	for (int i=0; i<10; i++) {
		dispatch_group_async( queueGroup,aQueue, ^{
			NSLog(@"A:%i",i);
		});
	}
	

	//在队列组中执行队列b
	for (int i=0; i<10; i++) {
		dispatch_group_async( queueGroup,bQueue, ^{
			NSLog(@"B:%i",i);
		});
	}
	
	dispatch_group_wait(queueGroup, DISPATCH_TIME_FOREVER);
	NSLog(@"end");
}

 执行fifthMethod方法后显示结果如下:

 

2012-04-10 16:43:50.701 Test04[2120:ae03] A:0

2012-04-10 16:43:50.702 Test04[2120:e203] B:0

2012-04-10 16:43:50.703 Test04[2120:ae03] A:1

2012-04-10 16:43:50.704 Test04[2120:e203] B:1

2012-04-10 16:43:50.705 Test04[2120:ae03] A:2

2012-04-10 16:43:50.705 Test04[2120:e203] B:2

2012-04-10 16:43:50.707 Test04[2120:ae03] A:3

2012-04-10 16:43:50.708 Test04[2120:e203] B:3

2012-04-10 16:43:50.709 Test04[2120:ae03] A:4

2012-04-10 16:43:50.710 Test04[2120:e203] B:4

2012-04-10 16:43:50.710 Test04[2120:ae03] A:5

2012-04-10 16:43:50.711 Test04[2120:e203] B:5

2012-04-10 16:43:50.711 Test04[2120:ae03] A:6

2012-04-10 16:43:50.712 Test04[2120:e203] B:6

2012-04-10 16:43:50.714 Test04[2120:ae03] A:7

2012-04-10 16:43:50.715 Test04[2120:e203] B:7

2012-04-10 16:43:50.716 Test04[2120:ae03] A:8

2012-04-10 16:43:50.717 Test04[2120:e203] B:8

2012-04-10 16:43:50.719 Test04[2120:ae03] A:9

2012-04-10 16:43:50.719 Test04[2120:e203] B:9

2012-04-10 16:43:50.721 Test04[2120:9203] end

 

 

9. Although you can obtain information about the underlying thread running a task, it is better to avoid doing so

 

10. 当你使用的是obj-c时, block会自动retain 被它包住的任何对象,当block执行完释放,所以你不必担心你在block内使用的obj-c对象会消失

当使用的是c时(CoreFoundation types in a C function), 你必须手动retain release,

 

void SaveArrayAsync(CFArrayRef array) {

    CFRetain(array);

 

    dispatch_queue_t queue = dispatch_get_global_queue(

                                 DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

 

    dispatch_async(queue, ^{

        SaveToDisk(array);

        CFRelease(array);

    }

 

11.  block的自动retain特性有时会造成互相引用,造成彼此都不能被释放, 可以用__block来解决这个问题,因为使用__block时不会retain

This copying/retaining semantics of blocks is very useful as it means your objects won’t go away while your block is being executed on some other thread, but you can also get into trouble if you happen to be using them only on one thread and the context in a block contains a reference to some parent structure. You’ll get into a retain-loop.

// inside your controller's tableView:cellForRowAtIndexPath:

cell = [[MyCell alloc] initWithBlock:^(MyCell* cell) {

           [self adjustCell:cell];

       }]; 

So here we have a block that calls a method on the controller. Simple enough. But when that cell is created, it’s init method might copy the block to ensure the block is valid at all times. The problem is, it references self. But that self is the view controller. So you have a view controller retained by one of its descendants. This creates a retained object loop that ultimately means this controller will never get released.

 

 __block variables are actually not retained when the lock is copied. So you can do this

 

// inside your controller's tableView:cellForRowAtIndexPath:

__block me = self;

cell = [[MyCell alloc] initWithBlock:^(MyCell* cell) {

           [me adjustCell:cell];

       }];

Since the self doesn’t get retained this time, we avoid the retain cycle. While it strikes me as iffy, it does work, and it’s the only way I’ve found to deal with this situation. You can’t simply avoid copying the block if you want to call it later, because the scope will be gone by the time the function that declared the block exits. That will lead to nothing but sadness.

 

 

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics