我的Swift应用程序中有两个视图。我正在执行一个segue如下。
ViewController.swift -----------------> GameViewController.swift
当加载GameViewController时,一个值数组也从ViewController. swift传递到GameViewController. swift
应该在GameViewController.swift中初始化计时器
我试图初始化一个计时器并通过它调用一个方法,但它不起作用。
下面是我的代码片段。
ViewController.swift
func signIn(difficultyLvl:String){
let username = usernameTxt.text
let password = passwordTxt.text
let url = URL(string: "http://192.168.1.106/speed/scoreBoardController.php?username="+username!+"&password="+password!+"&action=SIGNIN")
let task = URLSession.shared.dataTask(with: url!) {(data, response, error) in
let isPassed = String(data: data!, encoding:.utf8)?.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
var gameViewControllerParams = [Int: [String: String]]()
gameViewControllerParams[0] = ["userId" : isPassed!]
gameViewControllerParams[1] = ["difficultyLvl" : difficultyLvl]
if(isPassed != "null"){
self.performSegue(withIdentifier: "gotoGame", sender: gameViewControllerParams)
}
}
task.resume()
}
GameViewController.swift
class GameViewController: UIViewController {
var gameViewControllerParams = [Int: [String: String]]()
override func viewDidLoad() {
super.viewDidLoad()
let _ = Timer.scheduledTimer(timeInterval: 1.0, target:self, selector: #selector(self.setCalculationLs), userInfo:nil,repeats: true)
}
func setCalculationLs(){
print("Timing")
}
}
3条答案
按热度按时间sshcrbum1#
计时器不能在后台队列上工作(如果没有一些技巧,包括创建运行循环或在现有的运行循环上手动调度它)。但是无论如何,您都不应该从主队列以外的任何地方启动任何UI更新。
因此,由于您从
URLSession
完成闭包(在后台队列上运行)调用performSegue
,因此它实际上也从后台队列运行viewDidLoad
。因此,调度定时器的尝试失败。为了解决这个问题,你必须手动将performSegue
代码调度到主队列:如果您不确定某些代码是否在主队列上运行,请参考the documentation。也可以使用分派前提条件:
这样,如果您意外地从后台队列调用了代码,它将(在调试版本中)停止应用程序。
与您当前的问题无关,但顺便说一句,为了避免计时器和视图控制器之间的强引用循环,您通常希望保留对计时器的引用,以便在视图消失时可以
invalidate
它(例如,在viewDidAppear
中创建计时器,并在viewDidDisappear
中删除它)。否则,您可能会在GameViewController
被删除后仍然保留它,例如:或者在iOS 10或更高版本中,您可以使用基于块的变体,其中
weak
引用self
,而deinit
中的invalidate
:yshpjwxd2#
我在一个segued视图控制器中工作时也遇到了这个问题。由于segue是作为主线程(主视图控制器)的后台线程执行的,因此在segued视图控制器中运行timer将不起作用。所以,知道定时器在后台线程中不起作用,我做了一些挖掘,发现了this Apple Documentation gem。
我在定时器后面添加了下面这行代码。计时器现在工作得很漂亮。它只是将计时器发送到主线程以供执行。
mhd8tkvw3#
我知道这不是这个特定问题的答案,但我的计时器没有触发,因为我考虑的是毫秒而不是秒的timeInterval。所以我的计时器没响。(或者,它最终会发射,但在我期望或需要它很久之后)。