使用Swift 1.2进行同步请求的GCDAsyncSocket

时间:2015-05-05 21:01:47

标签: ios swift asynchronous sync gcdasyncsocket

背景

我在Swift 1.2上成功使用GCDAsyncSocket(通过桥接头)。

现在的挑战是它需要某种队列,因为它连接的系统一次只能处理和返回一个命令。

因此,如果它背靠背调用方法,例如:

getSystemInfo()
getSystemStatus()

仅通过委托回调返回getSystemInfo(),因为系统正在忙于处理它,但getSystemStatus()已成功发送asynchronously但未由控制器处理。我希望它能够重新进行调用,并在控制器完成处理并返回之前的响应后让它们排队并处理 - 基本上使进程同步。

问题:

正如您在didConnectToHost委托回调下的示例代码中所见,当它连接到控制器时,它会调用getSystemInfo()然后调用getSystemStatus(),它应该调用{ {1}}从系统信息中获取结果后。

我一直在关注getSystemStatus()NSCondition,甚至是GCD,但我不确定最优雅的方法是什么。我不想在混合中添加另一个队列处理器,因为已经有NSOperation的队列设置。处理这个问题最好,最优雅的方法是什么?

伪类代码:

GCDAsyncSocket

任何建议都会很棒 - 谢谢!

1 个答案:

答案 0 :(得分:3)

所以我决定使用NSOperation。

使用以下代码创建了一个名为SyncRequest.swift的类文件:

import Foundation

class SyncRequest : NSOperation {

 var socket:GCDAsyncSocket! = nil
 var msgData:NSData! = nil

 override var concurrent: Bool {
   return false
 }

 override var asynchronous: Bool {
   return false
 }

 private var _executing: Bool = false
 override var executing: Bool {
    get {
        return _executing
    }
    set {
        if (_executing != newValue) {
            self.willChangeValueForKey("isExecuting")
            _executing = newValue
            self.didChangeValueForKey("isExecuting")
        }
    }
}

private var _finished: Bool = false;
override var finished: Bool {
    get {
        return _finished
    }
    set {
        if (_finished != newValue) {
            self.willChangeValueForKey("isFinished")
            _finished = newValue
            self.didChangeValueForKey("isFinished")
        }
    }
}

/// Complete the operation
func completeOperation() {
    executing = false
    finished  = true
}

override func start() {
    if (cancelled) {
        finished = true
        return
    }

    executing = true

    main()
}


 override func main() -> (){
    println("starting...")

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "didReadData:", name: "DidReadData", object: nil)

    sendData()
}


    func sendData() {
        socket.writeData(msgData, withTimeout: -1.0, tag: 0)
        println("Sending: \(msgData)")
        socket.readDataWithTimeout(-1.0, tag: 0)
    }


    func didReadData(notif: NSNotification) {
        println("Data Received!")

        NSNotificationCenter.defaultCenter().removeObserver(self, name: "DidReadData", object: nil)

        completeOperation()

    }

}

然后,当我需要向控制器发送内容时,我会执行以下操作:

// sync the request to the controller
let queue = NSOperationQueue() // sync request queue
let requestOperation = SyncRequest()
requestOperation.socket = socket // pass the socket  to send through
requestOperation.msgData = msgData // pass the msgData to send
queue.maxConcurrentOperationCount = 1
queue.addOperation(requestOperation)

当数据从你处理GCDAsyncSocket" didReadData"的地方进来时,不要忘记发送NSNotification。委派。

public func socket(socket : GCDAsyncSocket!, didReadData data:NSData!, withTag tag:Int){

  ...
  NSNotificationCenter.defaultCenter().postNotificationName("DidReadData", object: data)
  ...

}