在使用新的 Swift 并发工具时发现了这个问题。
这是设置:
class FailedDeinit {
init() {
print(#function, id)
task = Task {
await subscribe()
}
}
deinit {
print(#function, id)
}
func subscribe() async {
let stream = AsyncStream<Double> { _ in }
for await p in stream {
print("\(p)")
}
}
private var task: Task<(), Swift.Error>?
let id = UUID()
}
var instance: FailedDeinit? = FailedDeinit()
instance = nil
Run Code Online (Sandbox Code Playgroud)
在 Playground 中运行此代码会产生以下结果:
init() F007863C-9187-4591-A4F4-BC6BC990A935
!!! 该deinit方法从未被调用!
奇怪的是,当我将代码更改为:
class SuccessDeinit {
init() {
print(#function, id) …Run Code Online (Sandbox Code Playgroud) 我注意到start(queue:)中的方法NWPathMonitor需要类型为 的队列DispatchQueue。有没有办法使用 Swift 现代并发来实现这一点,可能使用AsyncStream?
使用Apple文档AsyncStream,我已经创建了扩展NWPathMonitor,但我无法启动NWPathMonitor显示器,任何建议将不胜感激,谢谢
extension NWPathMonitor {
static var nwpath: AsyncStream<NWPath> {
AsyncStream { continuation in
let monitor = NWPathMonitor()
monitor.pathUpdateHandler = { path in
continuation.yield(path)
}
continuation.onTermination = { @Sendable _ in
monitor.cancel()
}
// monitor.start(queue: )
}
}
}
Run Code Online (Sandbox Code Playgroud)
阅读苹果的文档
我正在尝试使用现代 Swift Concurrency 构建分块文件上传机制。有一个流式文件读取器,我用它来逐块读取 1mb 大小的文件。它有两个闭包nextChunk: (DataChunk) -> Void和completion: () - Void。InputStream第一个被调用的次数与从块大小读取的数据一样多。
为了使该阅读器兼容 Swift Concurrency,我进行了扩展并创建了AsyncStream
似乎最适合这种情况的扩展。
public extension StreamedFileReader {
func read() -> AsyncStream<DataChunk> {
AsyncStream { continuation in
self.read(nextChunk: { chunk in
continuation.yield(chunk)
}, completion: {
continuation.finish()
})
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用它,AsyncStream我迭代地读取一些文件并进行如下网络调用:
func process(_ url: URL) async {
// ...
do {
for await chunk in reader.read() {
let request = // ...
_ = try await service.upload(data: chunk.data, request: …Run Code Online (Sandbox Code Playgroud) async-await swift structured-concurrency asyncstream asyncsequence