Моя функция внизу создает CFSocket
и пытается создать входные и выходные потоки с владельцем оригинальной функции в качестве делегата.Как вы передаете функцию обратного вызова CFSocket ссылку на себя при использовании Swift?
@objc
public class BonjourPublisher: NSObject, NSNetServiceDelegate, NSStreamDelegate {
private func hookUpSocket(fd: CFSocketNativeHandle) throws {
var context = CFSocketContext()
var selfPtr = self
withUnsafeMutablePointer(&selfPtr) {
context.info = UnsafeMutablePointer<Void>($0)
}
serviceSocket = withUnsafePointer(&context) {
CFSocketCreateWithNative(nil, fd, CFSocketCallBackType.AcceptCallBack.rawValue, CallbackListen, UnsafePointer<CFSocketContext>($0))
}
guard serviceSocket != nil && CFSocketIsValid(serviceSocket) else {
throw BonjourServerError.CreatingNativeSocket
}
serviceRunLoopSource = CFSocketCreateRunLoopSource(nil, serviceSocket, 0)
guard serviceRunLoopSource != nil && CFRunLoopSourceIsValid(serviceRunLoopSource) else {
throw BonjourServerError.CreatingSocketRunLoopSource
}
CFRunLoopAddSource(CFRunLoopGetCurrent(), serviceRunLoopSource, kCFRunLoopCommonModes)
}
}
func CallbackListen(s: CFSocket!, callbackType: CFSocketCallBackType, address: CFData!, data: UnsafePointer<Void>, info: UnsafeMutablePointer<Void>) {
let fd = UnsafePointer<CFSocketNativeHandle>(data)
var readStream: Unmanaged<CFReadStreamRef>?
var writeStream: Unmanaged<CFWriteStreamRef>?
CFStreamCreatePairWithSocket(nil, fd.memory, &readStream, &writeStream)
let inputStream: NSInputStream = readStream!.takeRetainedValue()
let outputStream: NSOutputStream = writeStream!.takeRetainedValue()
inputStream.setProperty(kCFBooleanTrue, forKey: kCFStreamPropertyShouldCloseNativeSocket as String)
let publisherPtr = UnsafeMutablePointer<BonjourPublisher>(info)
let publisher: BonjourPublisher = publisherPtr.memory
inputStream.delegate = publisher
outputStream.delegate = publisher
inputStream.open()
outputStream.open()
}
Но первая строка для обозначения publisherPtr.memory
получает EXC_BAD_ACCESS
исключение. В чем проблема? Это проблема ARC, или я испортил мой указатель?
Это может быть то, что вы ищете: [Swift 2 - UnsafeMutablePointer объекта] (http://stackoverflow.com/questions/30786883/swift-2-unsafemutablepointervoid-to-object). Дополнительная информация здесь: [Как направить себя на UnsafeMutablePointer type in swift] (http://stackoverflow.com/questions/33294620/how-to-cast-self-to-unsafemutablepointervoid-type-in-swift). –
Проблема в вашем коде заключается в том, что вы передаете адрес * локальной переменной * 'var selfPtr' для обратного вызова. Этот адрес становится недействительным, как только функция 'hookUpSocket()' возвращается. –
@MartinR Итак, я переключился на непрозрачные указатели, как рекомендует первая ссылка, и избавилась от исключений. К сожалению, у меня есть некоторые другие проблемы, но похоже, что это ответ на вопрос. Вы хотите опубликовать ответ? – Dov