Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift2,在CFSocketCallBack-EXEC\u BAD\u访问中调用swift函数_Swift_Pointers_Callback_Swift2_Cfsocket - Fatal编程技术网

Swift2,在CFSocketCallBack-EXEC\u BAD\u访问中调用swift函数

Swift2,在CFSocketCallBack-EXEC\u BAD\u访问中调用swift函数,swift,pointers,callback,swift2,cfsocket,Swift,Pointers,Callback,Swift2,Cfsocket,我正试图在Swift2.1.1中为MacOSX编写一个Xcode:7.2.1的套接字服务器应用程序。指。 但是我不能在socketCallBack函数中调用swift函数。 我的密码在这里。我正在通过自我的基础上回答在。我认为代码的这部分工作正常 class myServer: NSObject { // sockets private var socketipv4: CFSocket! private var socketipv6: CFSocket! // Connect

我正试图在Swift2.1.1中为MacOSX编写一个Xcode:7.2.1的套接字服务器应用程序。指。 但是我不能在socketCallBack函数中调用swift函数。
我的密码在这里。我正在通过自我的基础上回答在。我认为代码的这部分工作正常

class myServer: NSObject {

  // sockets
  private var socketipv4: CFSocket!
  private var socketipv6: CFSocket!

  // Connections
  var connections = Set<SPFConnection>()

  func start(address: String) -> Bool {

    var sockCtxt = CFSocketContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
    sockCtxt.info = UnsafeMutablePointer(unsafeAddressOf(self))

    // create socket with CFSocketCreate
    socketipv4 = CFSocketCreate(
        kCFAllocatorDefault,
        PF_INET,
        SOCK_STREAM,
        IPPROTO_TCP,
        kCFSocketAutomaticallyReenableAcceptCallBack,
        socketCallBack,
        &sockCtxt)

    // ipv4
    var sin = sockaddr_in()  // = initStruct()
    let server_addr_size = socklen_t(INET_ADDRSTRLEN)
    sin.sin_len = UInt8(server_addr_size)
    sin.sin_family = sa_family_t(AF_INET)
    sin.sin_port = UInt16(9999).bigEndian
    sin.sin_addr.s_addr = inet_addr(address)

    let sinData = NSData(bytes: &sin, length: sizeof(sockaddr_in))
    let ptr = UnsafePointer<UInt8>(sinData.bytes)

    let sincfd = CFDataCreate(kCFAllocatorDefault, ptr, sizeof(sockaddr_in))

    let ipv4SocketError: CFSocketError = CFSocketSetAddress(socketipv4, sincfd)
    switch ipv4SocketError {
    case .Success:
        print("ipv4 Success")
    default:
        print("ipv4 error = \(ipv4SocketError.rawValue)")
        return false
    }

    let socketSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socketipv4, 0)
    CFRunLoopAddSource(CFRunLoopGetCurrent(), socketSource, kCFRunLoopDefaultMode)

    return true
  }

  // CFSocket call back
  var socketCallBack : @convention(c)(CFSocket!, CFSocketCallBackType, CFData!, UnsafePointer<Void>, UnsafeMutablePointer<Void>) -> Void = {
    (socketRef, callbackType, address, data, info) in

    print("acceptConnection callback-ed") // \(socketRef), \(callbackType), \(address), \(data),\(info)")

    var tempData: CFSocketNativeHandle = 0
    var anNSData:NSData = NSData(bytes: data, length: sizeofValue(data))
    anNSData.getBytes(&tempData, length: sizeof(CFSocketNativeHandle))

    var tempAry = [UnsafeMutablePointer<Void>]()
    tempAry.append(info)
    if callbackType == CFSocketCallBackType.AcceptCallBack {
        let server = unsafeBitCast(info, myServer.self)
        // **** EXEC_BAD_ACCESS, code=2 ***** //
        server.acceptConnection(tempData)
    } else {
        print("callbacktype = \(callbackType.rawValue)")
    }
  }


  func acceptConnection(data: CFSocketNativeHandle) {
    print("acceptConnection called")
    var readStream: Unmanaged<CFReadStream>?
    var writeStream: Unmanaged<CFWriteStream>?

    CFStreamCreatePairWithSocket(kCFAllocatorDefault, data, &readStream, &writeStream)
    if readStream != nil && writeStream != nil {
        CFReadStreamSetProperty(readStream!.takeUnretainedValue(), kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue)
        CFWriteStreamSetProperty(writeStream!.takeUnretainedValue(), kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue)

        let connection = SPFConnection()
        connection.inputStream = readStream!.takeRetainedValue()
        connection.outputStream = writeStream!.takeRetainedValue()

        if connection.open() {
            connections.insert(connection)
        }
    }
  }
}
类myServer:NSObject{
//插座
私有变量socketipv4:CFSocket!
私有变量socketipv6:CFSocket!
//联系
var connections=Set()
func start(地址:字符串)->Bool{
var sockCtxt=CFSocketContext(版本:0,信息:nil,保留:nil,发布:nil,副本描述:nil)
sockCtxt.info=UnsafeMutablePointer(unsafeAddressOf(self))
//使用CFSocketCreate创建套接字
socketipv4=CFSocketCreate(
KCO默认值,
PF_INET,
苏克河,
IPPROTO_TCP,
KCFSocketAutomaticallyReeneableAcceptCallback,
socketCallBack,
&sockCtxt)
//ipv4
var sin=sockaddr_in()/=initStruct()
让服务器\u addr\u size=socklen\u t(INET\u ADDRSTRLEN)
sin.sin\u len=UInt8(服务器地址大小)
sin.sin_family=sa_family(AF_INET)
sin.sin_port=UInt16(9999).bigEndian
sin.sin\u addr.s\u addr=inet\u addr(地址)
设sinData=NSData(字节:&sin,长度:sizeof(sockaddr_in))
设ptr=UnsafePointer(sinData.bytes)
让sincfd=CFDataCreate(kcfolcatordefault、ptr、sizeof(sockaddr_in))
让ipv4SocketError:CFSocketError=CFSocketSetAddress(socketipv4,sincfd)
开关ipv4SocketError{
成功案例:
打印(“ipv4成功”)
违约:
打印(“ipv4错误=\(ipv4SocketError.rawValue)”)
返回错误
}
让socketSource=CFSocketCreateRunLoopSource(kCFAllocatorDefault,socketipv4,0)
CFRunLoopAddSource(CFRunLoopGetCurrent(),socketSource,kCFRunLoopDefaultMode)
返回真值
}
//CFSocket回调
var socketCallBack:@convention(c)(CFSocket!、CFSocketCallBackType、CFData!、UnsafePointer、UnsafeMutablePointer)->Void={
(socketRef、callbackType、地址、数据、信息)
打印(“接受连接回调”)//\(socketRef),\(回调类型),\(地址),\(数据),\(信息)”
var tempData:CFSocketNativeHandle=0
var anNSData:NSData=NSData(字节:数据,长度:sizeofValue(数据))
anNSData.getBytes(&tempData,长度:sizeof(CFSocketNativeHandle))
var tempAry=[Unsafemeutablepointer]()
临时追加(信息)
如果callbackType==CFSocketCallBackType.AcceptCallBack{
let server=unsafeBitCast(info,myServer.self)
//****执行错误访问,代码=2****//
server.acceptConnection(tempData)
}否则{
打印(“callbacktype=\(callbacktype.rawValue)”)
}
}
func acceptConnection(数据:CFSocketNativeHandle){
打印(“接受调用的连接”)
var readStream:非托管?
var writeStream:非托管?
CFStreamCreatePairWithSocket(kCFAllocatorDefault、数据、读取流和写入流)
如果readStream!=nil&&writeStream!=nil{
CFReadStreamSetProperty(readStream!.TakeUnrepainedValue(),kCFStreamPropertyShouldCloseNativeSocket,kCFBooleanTrue)
CFWriteStreamSetProperty(writeStream!.TakeUnrepainedValue(),kCFStreamPropertyShouldCloseNativeSocket,kCFBooleanTrue)
let connection=SPFConnection()
connection.inputStream=readStream!.takeRetainedValue()
connection.outputStream=writeStream!.takeRetainedValue()
if connection.open(){
连接。插入(连接)
}
}
}
}
我在代码服务器上得到EXEC\u BAD\u ACCESS code=2。acceptConnection(tempData)。
调试器为信息和服务器显示相同的指针,这意味着信息(self)已正确分配给服务器。 但EXEC_BAD_访问似乎意味着self不再可用。 我正在努力寻找解决方案。如果有人能给我任何建议, 非常感谢。
提前感谢您的帮助。

我承认我不太了解如何使用这些低级C约定,但是由于回调函数是类的一部分,所以不能只说self.acceptConnection(tempData)?

我猜在调用回调之前,myServer实例已被解除分配。您是否在某处维护对服务器的引用?可能的方法是什么?从视图控制器调用myServer,但不保留它,而是由let server=myServer()和server.start()创建的实例调用以调用函数。我曾尝试使用takeRetainValue(),但编译器不喜欢它,因此未设法保留实例。您可以将
server
作为视图控制器的属性(如果该属性持续存在),或应用程序委托,或者最好创建一个全局共享实例…@MartinR确实非常感谢。我现在没有收到错误。我希望我可以考虑在视图控制器中创建属性,而不是尝试将实例保留在其他地方。CFSocketCreate()是一个C函数,以C函数指针作为回调参数。在Swift中,只能传递不捕获任何状态的全局函数或闭包(这就是
@convention(C)
注释所代表的)。因此,socketCallBack闭包中没有
self
。这就是为什么您必须将
self
转换为空指针,将其作为信息指针传递给回调,然后将其转换回。是的,我一保存就意识到您可能无法。这对我来说很有趣,我现在从您在上面的评论,但我现在将坚持安全代码!LOL@Dan谢谢你的回答。我可以用Martin R的建议来避免这个错误。我很好奇你所说的“坚持安全代码”“。据我所知,一个应用程序只有两个选项需要监听端口,CFSocket或POSIX。你是说高级API也可以吗?如果是的话,我想知道。如有任何建议,请告知