Swift 闭包捕获上下文
当我尝试更改闭包中的变量时,会出现以下错误:Swift 闭包捕获上下文,swift,callback,closures,Swift,Callback,Closures,当我尝试更改闭包中的变量时,会出现以下错误: 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 = { (readStr
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
// 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)
是否有解决方法,或者是否仍然可以更改闭包中的变量
我的代码:
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)
let回调:@convention(c)(readStream:CFWriteStream!,事件:cfstreamventtype,数据:UnsafeMutablePointer)->Void={
(读取流、事件、数据)->Void in
切换事件{
案例cfstreamventtype.error发生:
self.isError=true
打破
案例CfStreamVentType.EndEnCounted:
self.isrunlop=false
打破
案例cfstreamventtype.hasbytes可用:
打破
案例cfstreamventtype.OpenCompleted:
打破
案例CFStreamVentType.CanAcceptBytes:
self.bytesWrite=CFWriteStreamWrite(读流、self.buffer、self.leftOverSize)
打破
违约:
打破
}
}
let registeredEvents:CFOptionFlags=
CFStreamEventType.CanAcceptBytes.rawValue|
cfstreamventtype.HasBytesAvailable.rawValue|
CFStreamEventType.ErrorOccurrend.rawValue|
cfstreamventtype.endencounted.rawValue|
cfstreamventtype.None.rawValue
var context=CFStreamClientContext(版本:CFIndex(0),信息:nil,保留:nil,发布:nil,副本描述:nil)
let stream=CFWriteStreamCreateWithFTPURL(nil,uploadURL)。takeUnrepainedValue()
CFWriteStreamSetClient(流、registeredEvents、回调和上下文)
我假设您希望使用此回调将其作为第三个参数(clientCB
)传递给
由于该参数具有以下类型定义
typedef void (*CFWriteStreamClientCallBack) ( CFWriteStreamRef stream, CFStreamEventType eventType, void *clientCallBackInfo );
您只能使用全局函数或不从周围上下文捕获任何变量(如self
)的闭包
在这种情况下,您可以将self
传递到CFStreamClientContext
结构的info
字段(CFWriteStreamSetClient的第四个参数),并使用该信息在闭包中重建self
:
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
// 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)
let回调:@convention(c)(readStream:CFWriteStream!,事件:cfstreamventtype,数据:UnsafeMutablePointer)->Void={
(读取流、事件、数据)->Void in
//假设您的类名是Client
let client=unsafeBitCast(data.memory,client.self)
切换事件{
案例cfstreamventtype.error发生:
client.isError=true
案例CfStreamVentType.EndEnCounted:
client.isrunlop=false
案例cfstreamventtype.hasbytes可用:
打破
案例cfstreamventtype.OpenCompleted:
打破
案例CFStreamVentType.CanAcceptBytes:
client.bytesWrite=CFWriteStreamWrite(readStream、client.buffer、client.leftOverSize)
违约:
打破
}
}
var context=CFStreamClientContext(版本:0,信息:unsafeBitCast(self,UnsafeMutablePointer.self),retain:nil,release:nil,copyDescription:nil)
CFWriteStreamSetClient(流、0、回调和上下文)
注意。与Objective-C一样,您需要确保
self
在流被销毁之前没有被销毁,否则如果流接收到新事件,您可能会崩溃。回调必须是一个全局函数或一个不捕获上下文的闭包。类似的问题:或者。我如何知道是否有错误?您必须将self
转换为空指针,将其作为用户数据传递给回调,然后在回调中将其转换回对象指针。另请参见。我一直收到以下错误:命令失败,原因是信号:分段错误:11
。在哪一行?如何调用CFWriteStreamSetClient
?@HovyTech这似乎是一个swift编译器问题,请参阅。但是,您将nil
传递给了CFStreamClientContext
的第二个参数,请查看我关于代码应该是什么样子的更新答案(假设Apple修复了编译器崩溃)