Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
606 views
in Technique[技术] by (71.8m points)

objective c - Toll-free bridging and pointer access in Swift

I am porting an App from Objective-C to Swift and I need to use the following method:

CFStreamCreatePairWithSocketToHost(alloc: CFAllocator!, host: CFString!, port: UInt32, 
readStream: CMutablePointer<Unmanaged<CFReadStream>?>, 
writeStream: CMutablePointer<Unmanaged<CFWriteStream>?>)

The old logic looks like this (which several web sites seem to agree on):

CFReadStreamRef readStream = NULL;
CFWriteStreamRef writeStream = NULL;
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)(host), port, 
                                   &readStream, &writeStream);

NSInputStream inputStream = (__bridge_transfer NSInputStream *)readStream;
NSOutputStream outputStream = (__bridge_transfer NSOutputStream *)writeStream;

Which works fine thanks to toll-free bridging. However, ARC does not exist in "Swift-space", and the type system has changed.

How do I turn my streams into instances of

CMutablePointer<Unmanaged<CFReadStream>?>, and
CMutablePointer<Unmanaged<CFWriteStream>?>

And then convert them back into NSStream subclasses after the CFStreamCreatePairWithSocketToHost call?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I got it to work, here's my code: Make sure you keep a reference of the connection class somewhere :-)

class Connection : NSObject, NSStreamDelegate {
    let serverAddress: CFString = "127.0.0.1"
    let serverPort: UInt32 = 8443

    private var inputStream: NSInputStream!
    private var outputStream: NSOutputStream!

    func connect() {
        println("connecting...")

        var readStream:  Unmanaged<CFReadStream>?
        var writeStream: Unmanaged<CFWriteStream>?

        CFStreamCreatePairWithSocketToHost(nil, self.serverAddress, self.serverPort, &readStream, &writeStream)

        // Documentation suggests readStream and writeStream can be assumed to
        // be non-nil. If you believe otherwise, you can test if either is nil
        // and implement whatever error-handling you wish.

        self.inputStream = readStream!.takeRetainedValue()
        self.outputStream = writeStream!.takeRetainedValue()

        self.inputStream.delegate = self
        self.outputStream.delegate = self

        self.inputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
        self.outputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)

        self.inputStream.open()
        self.outputStream.open()
    }

    func stream(stream: NSStream, handleEvent eventCode: NSStreamEvent) {
        println("stream event")
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...