系统提供的dispatch方法

本文介绍了GCD(Grand Central Dispatch)在iOS开发中的多种使用场景,包括后台执行、主线程执行、一次性执行及延迟执行等。同时,还详细阐述了如何自定义dispatch_queue_t,并演示了如何通过dispatch_group_t实现后台任务的并行执行与结果汇总。

为了方便地使用GCD,苹果提供了一些方法方便我们将block放在主线程或后台线程执行,或者延后执行。使用的例子如下所示:

 //  后台执行:
 dispatch_async(dispatch_get_global_queue(0, 0), ^{
      // something
 });

 // 主线程执行:
 dispatch_async(dispatch_get_main_queue(), ^{
      // something
 });

 // 一次性执行:
 static dispatch_once_t onceToken;
 dispatch_once(&onceToken, ^{
     // code to be executed once
 });

 // 延迟2秒执行:
 double delayInSeconds = 2.0;
 dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
 dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
     // code to be executed on the main queue after delay
 });

dispatch_queue_t也可以自己定义,如要自定义queue,可以用dispatch_queue_create方法,示例如下:

 // 自定义dispatch_queue_t
 dispatch_queue_t urls_queue = dispatch_queue_create("blog.devtang.com", NULL);
 dispatch_async(urls_queue, ^{  
   // your code 
 });
 dispatch_release(urls_queue);

另外,GCD还有一些高级用法,例如让后台两个线程并行执行,然后等两个线程都结束后,再汇总执行结果。这个可以用dispatch_group_t、dispatch_group_async、dispatch_group_notify来实现,示例如下:

 // 合并汇总结果
 dispatch_group_t group = dispatch_group_create();
 dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
      // 并行执行的线程一
 });
 dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
      // 并行执行的线程二
 });
 dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{
      // 汇总结果
 });

文章来自唐巧《iOS开发进阶》


<think> 我们收到了用户关于Dispatch的详细介绍及使用方法的请求。根据之前的对话历史,用户似乎对COM组件中的Dispatch(如win32com.client.Dispatch)和Grand Central DispatchGCD)都有兴趣。然而,结合引用内容,用户提供的引用[1]涉及COM组件的底层调用,引用[2][3][5]涉及iOS的GCD,引用[4]涉及Java的dispatch方法。因此,我们需要分多个方面来详细介绍Dispatch。 由于用户没有明确指定是哪一个Dispatch,我们将涵盖以下三个主要方面: 1. Windows COM组件中的Dispatch(重点参考引用[1]) 2. iOS/macOS中的Grand Central DispatchGCD)(重点参考引用[2][3][5]) 3. 简要提及其他环境中的Dispatch(如Java,参考引用[4]) 我们将按照以下结构组织回答: - COM Dispatch(win32com)的详细介绍与使用 - Grand Central Dispatch (GCD) 的详细介绍与使用 - 其他Dispatch的简要说明 - 常见问题解答 - 生成相关问题 注意:引用内容将作为补充材料,在适当位置引用。 # COM Dispatch (win32com) 的详细介绍与使用 ## 基本概念 `Dispatch` 是 Windows COM(Component Object Model)技术中的核心机制,用于创建和操作COM对象。在Python中,通常使用`win32com.client.Dispatch`来创建COM对象的实例。例如,操作Excel应用: ```python import win32com.client # 创建Excel应用实例 excel_app = win32com.client.Dispatch('Excel.Application') excel_app.Visible = True # 设置为可见 ``` ### 原理 当调用`win32com.client.Dispatch(prog_id)`时,系统会查找注册表中与该`prog_id`(如'Excel.Application')关联的COM组件,并创建该组件的实例。返回的对象是一个`CDispatch`对象,它封装了COM接口`IDispatch`。通过`IDispatch`接口,我们可以调用方法或访问属性,这背后是通过`IDispatch::Invoke`方法实现的[^1]。 ## 使用指南 ### 1. 创建对象 ```python # 创建Word应用 word_app = win32com.client.Dispatch('Word.Application') # 创建文件系统对象 fso = win32com.client.Dispatch('Scripting.FileSystemObject') ``` ### 2. 调用方法和属性 ```python # 打开工作簿 workbook = excel_app.Workbooks.Open(r'C:\test.xlsx') # 读取单元格值 sheet = workbook.Sheets(1) cell_value = sheet.Range('A1').Value ``` 注意:引用[2]中强调,调用方法时参数格式必须正确。例如,`Range`的参数必须是连续区域(如`A1:B5`),不连续区域(如`A1,B5`)会导致错误。 ### 3. 事件处理 `win32com`也支持事件处理,需要先创建`WithEvents`类: ```python class ExcelEvents: def OnWorkbookOpen(self, workbook): print(f"Workbook opened: {workbook.Name}") # 绑定事件 excel_event = win32com.client.WithEvents(excel_app, ExcelEvents) ``` ### 4. 异常处理 每次调用都可能抛出`pywintypes.com_error`异常,需捕获处理: ```python try: cell_value = sheet.Range('InvalidRange').Value except win32com.client.pythoncom.com_error as e: print(f"COM Error: {e.excepinfo[2]}") ``` ### 5. 资源释放 使用后必须释放资源,否则会导致应用程序驻留内存: ```python workbook.Close(False) # 关闭工作簿,不保存 excel_app.Quit() # 退出Excel应用 ``` # Grand Central Dispatch (GCD) 的详细介绍与使用 GCD是苹果为iOS和macOS提供的并发编程解决方案。它基于队列(queue)和任务(task)的概念,自动管理线程生命周期。 ## 基本概念 ### 队列(Dispatch Queue) - **串行队列(Serial Queue)**:任务按顺序执行 - **并发队列(Concurrent Queue)**:任务并行执行(系统提供全局并发队列) - **主队列(Main Queue)**:串行队列,在应用主线程运行 ### 任务(Task) - **同步任务(dispatch_sync)**:阻塞当前线程直到任务完成 - **异步任务(dispatch_async)**:不阻塞当前线程 ## 使用指南(Swift语言) ### 1. 获取队列 ```swift // 主队列 let mainQueue = DispatchQueue.main // 全局并发队列 let globalQueue = DispatchQueue.global(qos: .default) // 创建自定义队列 let serialQueue = DispatchQueue(label: "com.example.serial") let concurrentQueue = DispatchQueue(label: "com.example.concurrent", attributes: .concurrent) ``` ### 2. 提交任务 ```swift // 异步提交到全局队列 DispatchQueue.global().async { // 后台耗时操作 let result = doHeavyWork() // 完成后回到主队列更新UI DispatchQueue.main.async { updateUI(with: result) } } ``` ### 3. 延时执行 ```swift DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { print("2秒后执行") } ``` ### 4. 迭代任务(dispatch_apply) 引用[3]中提到的`dispatch_apply`函数在Swift中为`concurrentPerform`: ```swift DispatchQueue.concurrentPerform(iterations: 100) { i in // 并行执行100次 processData(index: i) } ``` ### 5. 组任务(Dispatch Group) ```swift let group = DispatchGroup() group.enter() downloadImage(url: url1) { image in group.leave() } group.enter() downloadImage(url: url2) { image in group.leave() } group.notify(queue: .main) { print("所有下载完成") } ``` ## 其他Dispatch的简要说明 ### Java中的Dispatch 引用[4]提到`dispatch_next()`方法,它是Java虚拟机执行字节码的一种机制。在Java中,方法分派(dispatch)通常指动态绑定(多态): ```java class Animal { void speak() { System.out.println("Animal sound"); } } class Dog extends Animal { @Override void speak() { System.out.println("Bark"); } } public class Main { public static void main(String[] args) { Animal myDog = new Dog(); myDog.speak(); // 动态分派,调用Dog的speak方法 } } ``` # 常见问题解答 1. **Q: COM Dispatch创建
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值