gpt4 book ai didi

swift - 闭包捕获上下文 Swift

转载 作者:搜寻专家 更新时间:2023-10-31 08:25:51 24 4
gpt4 key购买 nike

当我尝试更改闭包中的变量时出现此错误:

A C function pointer cannot be formed from a closure that captures context

是否有变通办法,或者仍然可以更改闭包中的变量?

我的代码:

let callback: @convention(c) (readStream: CFWriteStream!, event: CFStreamEventType, data: UnsafeMutablePointer<Void>) -> Void = {
(readStream, event, data) -> Void in
switch event {
case CFStreamEventType.ErrorOccurred:
self.isError = true
break
case CFStreamEventType.EndEncountered:
self.isRunLoop = false
break
case CFStreamEventType.HasBytesAvailable:
break
case CFStreamEventType.OpenCompleted:
break
case CFStreamEventType.CanAcceptBytes:
self.bytesWritten = CFWriteStreamWrite(readStream, self.buffer, self.leftOverSize)
break
default:
break
}
}

let registeredEvents: CFOptionFlags =
CFStreamEventType.CanAcceptBytes.rawValue |
CFStreamEventType.HasBytesAvailable.rawValue |
CFStreamEventType.ErrorOccurred.rawValue |
CFStreamEventType.EndEncountered.rawValue |
CFStreamEventType.None.rawValue

var context = CFStreamClientContext(version: CFIndex(0), info: nil, retain: nil, release: nil, copyDescription: nil)
let stream = CFWriteStreamCreateWithFTPURL(nil, uploadURL).takeUnretainedValue()

CFWriteStreamSetClient(stream, registeredEvents, callback, &context)

最佳答案

我假设您想使用此回调将其作为第三个参数 (clientCB) 传递给 CFWriteStreamSetClient .

由于该参数具有以下类型定义

typedef void (*CFWriteStreamClientCallBack) ( CFWriteStreamRef stream, CFStreamEventType eventType, void *clientCallBackInfo );

您只能使用全局函数或不从周围上下文捕获任何变量(如 self)的闭包。

在这种情况下你可以做的是将 self 传递给 CFStreamClientContext 结构的 info 字段( 的第 4 个参数>CFWriteStreamSetClient),并使用该信息在闭包中重建 self:

let callback: @convention(c) (readStream: CFWriteStream!, event: CFStreamEventType, data: UnsafeMutablePointer<Void>) -> Void = {
(readStream, event, data) -> Void in
// assuming your class name is Client
let client = unsafeBitCast(data.memory, Client.self)
switch event {
case CFStreamEventType.ErrorOccurred:
client.isError = true
case CFStreamEventType.EndEncountered:
client.isRunLoop = false
case CFStreamEventType.HasBytesAvailable:
break
case CFStreamEventType.OpenCompleted:
break
case CFStreamEventType.CanAcceptBytes:
client.bytesWritten = CFWriteStreamWrite(readStream, client.buffer, client.leftOverSize)
default:
break
}
}

var context = CFStreamClientContext(version: 0, info: unsafeBitCast(self, UnsafeMutablePointer<Void>.self), retain: nil, release: nil, copyDescription: nil)
CFWriteStreamSetClient(stream, 0, callback, &context)

注意。与 Objective-C 一样,您需要确保 self 在流被销毁之前没有被销毁,否则如果流接收到新事件,您可能会崩溃。

关于swift - 闭包捕获上下文 Swift,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35346955/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com