NSTimer永远不会调用选择器功能(Swift)
问题描述:
保持冷静,很可能这个问题不是重复的。 我已经尝试了所有的堆栈溢出解决方案,但没有为我工作。 我有一个客户端线程发送和接收来自另一主机的“keepalive”字符串(ping)。如果它没有收到KeepAliveMax中的“Keepalive”,它会关闭这些流并说再见(理论上,但这还没有起作用)。 现在我的问题是,我用一个NSTimer调用updateKeepAlive函数,但它永远不会被调用..我不明白为什么:( 我也尝试过手动设置NSTimer RunLoop,但它不起作用NSTimer永远不会调用选择器功能(Swift)
后续是代码的一部分,其中选择器功能应该被初始化,并呼吁每一秒:
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 .....
........./*
}
答
在一个新的线程开始时,有没有inp ut源或定时器附加到运行循环。所以运行循环,而不是积极的。您可以在调用scheduledTimerWithTimeInterval之后调用run函数。
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(TimerTest.updateKeepAlive), userInfo: nil, repeats: true)
NSRunLoop.currentRunLoop().run()