加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

关闭捕获上下文Swift

发布时间:2020-12-14 04:37:20 所属栏目:百科 来源:网络整理
导读:当我尝试更改闭包中的变量时,我收到此错误: A C function pointer cannot be formed from a closure that captures context 是否有解决方法或是否仍然可以更改闭包内的变量? 我的代码: let callback: @convention(c) (readStream: CFWriteStream!,event:
当我尝试更改闭包中的变量时,我收到此错误:

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字段(CFWriteStreamSetClient的第4个参数),并使用该信息在闭包内重构self:

let callback: @convention(c) (readStream: CFWriteStream!,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),copyDescription: nil)
CFWriteStreamSetClient(stream,&context)

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读