不从scheduledTimerWithTimeInterval触发选择器

时间:2021-08-19 20:37:45

I checked the existing posts on this topic and also googled it, but I am not able to identify my mistake or make this work for me. I have a function iterativeDeepening() inside the class ChessPlayer. After say 15 seconds I want to stop further iterations within the function. In the code below, the function "flagSetter" is never invoked. If I use NSTimer.fire() the function is invoked immediately and not after 15 seconds. I tried placing the flagSetter function before or after iterativeDeepening(). Either case does not work. What have I done incorrectly?

我检查了这个主题的现有帖子,并用Google搜索,但我无法识别我的错误或让我的工作。我在类ChessPlayer中有一个函数iterativeDeepening()。说15秒后,我想停止函数内的进一步迭代。在下面的代码中,永远不会调用函数“flagSetter”。如果我使用NSTimer.fire(),则立即调用该函数,而不是在15秒后调用。我尝试在iterativeDeepening()之前或之后放置flagSetter函数。这两种情况都不起作用。我做错了什么?

class ChessPlayer {
    var timeoutFlag = false
    //Code

    func iterativeDeepening() {

        ***//variables and constants***

        let timer = NSTimer.scheduledTimerWithTimeInterval(15.0, target: self, selector: #selector(self.flagSetter), userInfo: nil, repeats: false)

        ***while minDepth <= maxDepth
        {
            // Loop iteration code
            if timeoutFlag { break out of loop }
        }***

    }

    @objc func flagSetter(timer: NSTimer) {
        print("flag changed to true")
        self.timeoutFlag = true
        timer.invalidate()
    }
}

The requirement:

  1. computerThinking() is fired from GameScene from human move's action completion handler.
  2. computerThinking()是从人类移动的动作完成处理程序中从GameScene触发的。

  3. GameScene.computerThinking() invokes ChessPlayer.iterativeDeepening()
  4. GameScene.computerThinking()调用ChessPlayer.iterativeDeepening()

  5. iterativeDeepening runs a while loop incrementing "depth". For each "depth" an optimal move at that depth is evaluated. Higher the depth, more detailed the evaluation.
  6. iterativeDeepening运行while循环递增“深度”。对于每个“深度”,评估在该深度处的最佳移动。深度越高,评估越详细。

  7. after 15.0 seconds i want to break out of the while loop with the depth and optimal move available at that point of time.
  8. 在15.0秒之后,我想要突破while循环,在那个时间点可以获得深度和最佳移动。

2 个解决方案

#1


0  

I am a lover of Objective-c and never used Swift yet in my projects. Googling NSTimer Swift, I found out the following steps to implement NSTimer correctly.

我是Objective-c的爱好者,在我的项目中从未使用过Swift。谷歌搜索NSTimer Swift,我发现以下步骤正确实现NSTimer。

we need to define our NSTimer. The first variable that we are going to need is a variable called timer of type NSTimer. We do this like:

我们需要定义我们的NSTimer。我们需要的第一个变量是名为NSTimer类型的计时器的变量。我们这样做:

var timer = NSTimer()

Start NSTimer timer:

启动NSTimer计时器:

timer = NSTimer.scheduledTimerWithTimeInterval(15.0, target:self, selector:#selector(ChessPlayer.flagSetter(_:)), userInfo: nil, repeats: false)

And your method flagSetter should be defined as this:

你的方法flagSetter应该定义如下:

func flagSetter(timer: NSTimer) {
        print("flag changed to true")
        self.timeoutFlag = true
        timer.invalidate()
}

This will now surely work as I've made my very first app, just for this question, made in Swift. Check how I put my selector. You're right with the warnings by the way.

现在这肯定会起作用,因为我已经制作了我的第一个应用程序,仅针对这个问题,在Swift中制作。检查我如何放置我的选择器。顺便说一下,你是对的警告。

If you need more information about Selectors, check this thread: @selector() in Swift?

如果您需要有关选择器的更多信息,请检查此线程:Swift中的@selector()?

#2


0  

Here is your solution: define timer outside of the function so you can invalidate it from another function. Right now, your timer is defined inside a function so it can only be altered inside that function, but that is not what you want. Fix it by doing the following: right below var timeoutFlag = false put var timer = NSTimer(). Then inside your function iterativeDeepening() get rid of the let. Then it will all work!!

这是您的解决方案:在函数外部定义计时器,以便您可以从另一个函数中使其无效。现在,你的计时器是在一个函数中定义的,所以它只能在那个函数内部改变,但这不是你想要的。通过执行以下操作来修复它:右下方var timeoutFlag = false put var timer = NSTimer()。然后在你的函数里面迭代Deepening()去掉let。那一切都会奏效!!


Here's what your code should be, adapted from Hasya's answer and your provided code.

这是您的代码应该是什么,改编自Hasya的答案和您提供的代码。

class ChessPlayer {
// Declare timer and timeoutFlag
var timer = NSTimer()   
var timeoutFlag = false

func iterativeDeepening() {

self.timer = NSTimer.scheduledTimerWithTimeInterval(15.0, target: self, selector: “timerEventOccured”, userInfo: nil, repeats: true)
}

func timerEventOccured() {
        print("timerEventOccured was called.")
        timeoutFlag = true
        self.timer.invalidate()
    }

}

override func viewDidUnload() {
super.viewDidUnload()
self.timer.invalidate()
}
}

#1


0  

I am a lover of Objective-c and never used Swift yet in my projects. Googling NSTimer Swift, I found out the following steps to implement NSTimer correctly.

我是Objective-c的爱好者,在我的项目中从未使用过Swift。谷歌搜索NSTimer Swift,我发现以下步骤正确实现NSTimer。

we need to define our NSTimer. The first variable that we are going to need is a variable called timer of type NSTimer. We do this like:

我们需要定义我们的NSTimer。我们需要的第一个变量是名为NSTimer类型的计时器的变量。我们这样做:

var timer = NSTimer()

Start NSTimer timer:

启动NSTimer计时器:

timer = NSTimer.scheduledTimerWithTimeInterval(15.0, target:self, selector:#selector(ChessPlayer.flagSetter(_:)), userInfo: nil, repeats: false)

And your method flagSetter should be defined as this:

你的方法flagSetter应该定义如下:

func flagSetter(timer: NSTimer) {
        print("flag changed to true")
        self.timeoutFlag = true
        timer.invalidate()
}

This will now surely work as I've made my very first app, just for this question, made in Swift. Check how I put my selector. You're right with the warnings by the way.

现在这肯定会起作用,因为我已经制作了我的第一个应用程序,仅针对这个问题,在Swift中制作。检查我如何放置我的选择器。顺便说一下,你是对的警告。

If you need more information about Selectors, check this thread: @selector() in Swift?

如果您需要有关选择器的更多信息,请检查此线程:Swift中的@selector()?

#2


0  

Here is your solution: define timer outside of the function so you can invalidate it from another function. Right now, your timer is defined inside a function so it can only be altered inside that function, but that is not what you want. Fix it by doing the following: right below var timeoutFlag = false put var timer = NSTimer(). Then inside your function iterativeDeepening() get rid of the let. Then it will all work!!

这是您的解决方案:在函数外部定义计时器,以便您可以从另一个函数中使其无效。现在,你的计时器是在一个函数中定义的,所以它只能在那个函数内部改变,但这不是你想要的。通过执行以下操作来修复它:右下方var timeoutFlag = false put var timer = NSTimer()。然后在你的函数里面迭代Deepening()去掉let。那一切都会奏效!!


Here's what your code should be, adapted from Hasya's answer and your provided code.

这是您的代码应该是什么,改编自Hasya的答案和您提供的代码。

class ChessPlayer {
// Declare timer and timeoutFlag
var timer = NSTimer()   
var timeoutFlag = false

func iterativeDeepening() {

self.timer = NSTimer.scheduledTimerWithTimeInterval(15.0, target: self, selector: “timerEventOccured”, userInfo: nil, repeats: true)
}

func timerEventOccured() {
        print("timerEventOccured was called.")
        timeoutFlag = true
        self.timer.invalidate()
    }

}

override func viewDidUnload() {
super.viewDidUnload()
self.timer.invalidate()
}
}