https://www.evernote.com/shard/s20/sh/54fbd735-53b6-4436-9bd4-88d46b628527/22bc221c73b55dbf1ddfb5515649c239
1. GCD 使用后不用程序去管理线程的开闭,GCD会在系统层面上去动态检测系统状态,开闭线程
dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
for (__block int i = 0; i<10000; i++) {
dispatch_async(aQueue, ^{
NSLog(@"%d",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] 10000dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
for (int i = 0; i<1000; i++) {
dispatch_async(aQueue, ^{
NSLog(@"%d",i);
});
}2011-07-05 17:15:37.525 ttt[41697:1803] 0
2011-07-05 17:15:37.526 ttt[41697:1803] 2
2011-07-05 17:15:37.527 ttt[41697:1803] 3
2011-07-05 17:15:37.527 ttt[41697:1803] 4
2011-07-05 17:15:37.527 ttt[41697:1803] 5
2011-07-05 17:15:37.527 ttt[41697:1803] 6
2011-07-05 17:15:37.526 ttt[41697:5f03] 1
2011-07-05 17:15:37.530 ttt[41697:5f03] 8
2011-07-05 17:15:37.530 ttt[41697:5f03] 9
2011-07-05 17:15:37.530 ttt[41697:5f03] 10
2011-07-05 17:15:37.530 ttt[41697:5f03] 11
2011-07-05 17:15:37.532 ttt[41697:6203] 13void myFinalizerFunction(){
NSLog(@"xxx");
}
- (void)viewDidLoad {
[superviewDidLoad];
dispatch_queue_t queue = dispatch_queue_create("com.example.MyQueue", NULL);
dispatch_set_context(queue, @"xxx");
dispatch_set_finalizer_f(queue, &myFinalizerFunction);
for (int i = 0; i<1000; i++) {
dispatch_async(queue, ^{
NSLog(@"%d",i);
});
}
dispatch_release(queue);7. dispatch_sync(queue,task)
会阻塞当前线程 直到queue完成了你给的task, 但queue要完成你给的task,因为queue是FIFO的,意味着要完成之前的任务,才有机会执行你刚才给的task, 相当于当前线程等待queue里面所有任务执行完毕, 所以这句话不能在当前queue的任务代码里面调用,会造成死锁
dispatch_queue_t queue = dispatch_queue_create("com.example.MyQueue", NULL);
dispatch_set_context(queue, @"xxx");
dispatch_set_finalizer_f(queue, &myFinalizerFunction);
for (int i = 0; i<10; i++) {
dispatch_async(queue, ^{
NSLog(@"%d",i);
});
}
NSLog(@"waiting");
dispatch_sync(queue, ^{
NSLog(@"wait done");
});
dispatch_release(queue);2011-07-05 17:54:35.479 ttt[44203:207] waiting
2011-07-05 17:54:35.479 ttt[44203:1803] 0
2011-07-05 17:54:35.481 ttt[44203:1803] 1
2011-07-05 17:54:35.482 ttt[44203:1803] 2
2011-07-05 17:54:35.482 ttt[44203:1803] 3
2011-07-05 17:54:35.483 ttt[44203:1803] 4
2011-07-05 17:54:35.483 ttt[44203:1803] 5
2011-07-05 17:54:35.484 ttt[44203:1803] 6
2011-07-05 17:54:35.484 ttt[44203:1803] 7
2011-07-05 17:54:35.485 ttt[44203:1803] 8
2011-07-05 17:54:35.485 ttt[44203:1803] 9
2011-07-05 17:54:35.486 ttt[44203:207] wait done
2011-07-05 17:54:35.487 ttt[44203:1803] xxxdispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
// Add a task to the group
dispatch_group_async(group, queue, ^{
NSLog(@"first task");
});
dispatch_queue_t otherqueue = dispatch_queue_create("com.example.MyQueue", NULL);
for (int i = 0; i<100; i++) {
dispatch_group_async(group, otherqueue, ^{
NSLog(@"otherqueue task");
});
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(@"end waiting");
2011-07-05 19:32:31.919 ttt[50138:5f03] otherqueue task
2011-07-05 19:32:31.919 ttt[50138:1803] first task
2011-07-05 19:32:31.922 ttt[50138:5f03] otherqueue task
2011-07-05 19:32:31.923 ttt[50138:5f03] otherqueue task
...
2011-07-05 19:32:32.078 ttt[50138:5f03] otherqueue task
2011-07-05 19:32:32.079 ttt[50138:5f03] otherqueue task
2011-07-05 19:32:32.080 ttt[50138:207] end waitingvoid 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);
}
}
// inside your controller's tableView:cellForRowAtIndexPath:
cell = [[MyCell alloc] initWithBlock:^(MyCell* cell) {
[self adjustCell:cell];
}];
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.