MST

星途 面试题库

面试题:Swift并发编程中Task的生命周期管理

在Swift并发编程里,Task有不同的生命周期状态。请阐述Task从创建到结束,可能经历哪些状态变化?并且描述如何优雅地取消一个Task,同时避免资源泄露等问题。
43.7万 热度难度
编程语言Swift

知识考点

AI 面试

面试题答案

一键面试

Task生命周期状态变化

  1. 待定(Pending):当通过Task { ... }创建一个Task时,它最初处于待定状态。此时Task尚未开始执行,等待调度到合适的执行环境。
  2. 活跃(Active):一旦Task开始执行其闭包中的代码,就进入活跃状态。在这个状态下,Task正在执行它的工作。
  3. 完成(Finished):当Task闭包中的代码正常执行完毕,没有抛出错误,Task就会进入完成状态。另外,如果Task因为未处理的错误而退出,也会进入完成状态。

优雅取消Task并避免资源泄露

  1. 使用CancellationToken:可以创建一个CancellationToken并传递给Task。在Task内部,通过检查Task.isCancelled属性或者在合适的异步操作中传递CancellationToken来响应取消请求。例如:
let cancellationToken = CancellationToken()
let task = Task {
    while !Task.isCancelled {
        // 执行任务
        try await Task.sleep(nanoseconds: 1_000_000_000)
    }
    // 清理资源
}
// 取消任务
cancellationToken.cancel()
  1. 在异步操作中传递CancellationToken:许多Swift异步函数支持接收CancellationToken。比如URLSession的异步数据加载方法。当传递的CancellationToken被取消时,相应的异步操作会被取消。
let session = URLSession.shared
let task = Task {
    let url = URL(string: "https://example.com")!
    do {
        let (data, _) = try await session.data(from: url, cancellationToken: cancellationToken)
        // 处理数据
    } catch {
        if let cancellationError = error as? CancellationError, cancellationError.isCancellationRequested {
            // 处理取消情况
        } else {
            // 处理其他错误
        }
    }
}
  1. 资源清理:在Task取消时,要确保对已分配的资源进行清理。例如关闭文件句柄、释放网络连接等。在上述例子中,在while循环之后可以添加清理资源的代码。如果使用了自定义资源管理类,该类可以实现deinit方法来确保在对象销毁时清理资源。

通过这些方法,可以优雅地取消Task并有效避免资源泄露问题。