标签:
block访问的外部变量都会被COPY一份到block自己在heap中分配的数据结构中。所以访问scalar变量没问题,简单的值COPY,但是尽量不要访问大的struct或者由外部语境创建和销毁的对象,因为在block执行的时候,对象可能已经不见了。(weak reference可以避免这个问题)。
- 定时器定时通知
- unix signal
- 文件描述符,文件句柄或者网络句柄变化通知:例如文件属性变化,网络数据到达
- 设备端口
- 进程
- 自己定制的
dispatch source可能会产生大量的事件,为了防止过度干扰,会合并这些事件。如果之前产生的事件没有被event handler进行处理,那么就会被新产生的事件合并掉。合并的策略根据source的类型而不同。例如:signal-based source会只保留最后一个事件,但是会表述自从最后一次event handler被调用之后,一共来过多少个siginal事件。timer-based source会只保留最后一个事件。
// Create the semaphore, specifying the initial pool size dispatch_semaphore_t fd_sema = dispatch_semaphore_create(getdtablesize() / 2); // Wait for a free file descriptor dispatch_semaphore_wait(fd_sema, DISPATCH_TIME_FOREVER); fd = open("/etc/services", O_RDONLY); // Release the file descriptor when done close(fd); dispatch_semaphore_signal(fd_sema);
#import <Foundation/Foundation.h> typedef struct _ContextData { int number; } ContextData; @interface ZNContextData : NSObject @property (nonatomic) int number; @end @interface ZNQueueContext : NSObject /** * 运行基于C结构的context例子 */ - (void) runStructContextSample; /** * 运行基于对象的context例子 */ - (void)runObjectContextSample; @end #import "ZNQueueContext.h" @implementation ZNContextData - (void)dealloc { NSLog(@"deallocating %@", self.class); } @end @implementation ZNQueueContext - (void) runStructContextSample { dispatch_queue_t queue = dispatch_queue_create("com.structqueue", DISPATCH_QUEUE_CONCURRENT); //创建context ContextData *data = malloc(sizeof(ContextData)); data->number = 10; //为队列设置context dispatch_set_context(queue, data); dispatch_set_finalizer_f(queue, finalizeForStruct); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //执行10遍 dispatch_apply(100, queue, ^(size_t t) { ContextData *data = (ContextData *)dispatch_get_context(queue); NSLog(@"current number: %d", data->number); data->number += 10; }); }); } - (void)runObjectContextSample { dispatch_queue_t queue = dispatch_queue_create("com.objectqueue", DISPATCH_QUEUE_SERIAL); ZNContextData *data = [[ZNContextData alloc] init]; data.number = 10; //这里讲对象管理权从ARC中接管过来,如果不接管,异步执行的时候,data早就被释放了 dispatch_set_context(queue, (__bridge_retained void*)data); dispatch_set_finalizer_f(queue, finalizeForObject); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //执行10遍 dispatch_apply(100, queue, ^(size_t t) { //这里只涉及类型转换,不涉及对象管理权的变化 ZNContextData *data = (__bridge ZNContextData *) dispatch_get_context(queue); NSLog(@"current number: %d", data.number); data.number += 10; }); }); } #pragma mark - c functions /** * 清除和释放struct * * @param context <#context description#> */ void finalizeForStruct(void *context) { ContextData *data = (ContextData *)context; data->number = 0; free(data); } void finalizeForObject(void *context) { //这里将对象的管理权交换给ARC管理 __unused ZNContextData *data = (__bridge_transfer ZNContextData *)context; }
标签:
原文地址:http://www.cnblogs.com/gabrialrx/p/4801506.html