NSTimer从不调用选择器函数(Swift)

时间:2016-07-23 13:59:01

标签: ios swift nstimer

保持冷静,最有可能这个问题不重复。 我已经尝试过堆栈溢出的所有解决方案,但没有任何方法可以帮助我。 我有一个客户端线程,发送和接收" keepalive"来自另一台主机的字符串(ping)。如果它没有收到" keepalive"在KeepAliveMax中,它关闭流并说再见(理论上,但这仍在进行中)。 现在我的问题是我使用NSTimer调用updateKeepAlive函数,但它永远不会被调用..我不明白为什么:( 我也尝试手动设置NSTimer RunLoop,但它不起作用

以下是代码的一部分,其中应该初始化选择器函数并每秒调用一次:

public class Client: NSObject, NSStreamDelegate  {

var serverAddress: CFString
let serverPort: UInt32 = 50000

private var inputStream: NSInputStream!
private var outputStream: NSOutputStream!
private var connecting:Bool
private var byteRead:Int
private var byteWrite:Int
private let keepAliveMax:Double = 5000
private var keepAliveTime:Double
private var connected:Bool
var timer: NSTimer?

init(ip:String) {
    serverAddress = ip
    connecting = false
    connected = false
    byteRead = 0
    byteWrite = 0
    keepAliveTime = 0

    super.init()

    let thread = NSThread(target:self, selector:#selector(connect), object:nil)

    thread.start()

    print("thread is started and now I can continue with other tasks..")

}

func connect() {

    connecting = true

    while connecting {
        print("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()

        // send handshake

        byteWrite = writeLine("handshake")
        print("written: \(byteWrite) for handshake")


        // wait to receive handshake
        print("waintig for handshake...")


        if readLine() == "handshake" {
            connected = true

            print("Client: connection estabilished correctly")

            // close the waiting popup and start with SendBox...
            // in progress...

            // send keepAlive
            byteWrite = writeLine("keepalive")
            print("written: \(byteWrite) for keepalive")


            //======================== THIS NOT WORK PROPERLY ============================================================

            timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(Client.updateKeepAlive), userInfo: nil, repeats: true)

            /*
             timer = NSTimer(timeInterval: 1, target: self, selector: #selector(Client.updateKeepAlive), userInfo: nil, repeats: true)

             NSRunLoop.currentRunLoop().addTimer(timer!, forMode: NSRunLoopCommonModes)
             */

            //============================================================================================================

            keepAliveTime = NSDate().timeIntervalSince1970 * 1000

            print("Client: Timer started")

            while self.inputStream.streamStatus != NSStreamStatus.Closed ||
                self.outputStream.streamStatus != NSStreamStatus.Closed
            {
                print("Client: under the while of keepAlive");

                if readLine() == "keepalive"
                {
                    keepAliveTime = NSDate().timeIntervalSince1970 * 1000
                    writeLine("keepalive")

                    print("Client: keepalive received");
                }
                else
                {
                    print("Client: not keepalive: ");
                    // close streams...... work in progress
                    break

                }

                sleep(1)
            }

        }
        else{
            print("wrong handshake")
        }


        print("closing streams..")
        connecting = false

        self.inputStream.close()
        self.outputStream.close()
        self.timer?.invalidate()
    }

}

以下是updateKeepAlive函数:

func updateKeepAlive(){

    print("in updateKeepalive function") // <---- NEVER PRINTED

    /*  in progress .....

    ........./*
}

1 个答案:

答案 0 :(得分:0)

在新线程开始时,没有输入源或定时器附加到运行循环。所以运行循环虽然没有激活。您可以在调用scheduledTimerWithTimeInterval后调用run函数。

timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(TimerTest.updateKeepAlive), userInfo: nil, repeats: true)
NSRunLoop.currentRunLoop().run()