如何使用 Swift 在自定义线程中运行计时器 [英] How to run Timer in custom Thread with Swift

查看:57
本文介绍了如何使用 Swift 在自定义线程中运行计时器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须做一个简单的任务 - 带有两个按钮和三个踏板的单视图应用程序 -

I have to make a simple task - singleview app with two buttons and three treads -

  1. 开始按钮:

1a) 创建一个线程 T1 - 每 3.0 重复收集设备的 GPS 位置秒,并将结果(作为字符串)交给 T3.

1a) create a thread T1 - the GPS location of the device is collected repeatedly every 3.0 seconds, and the results (as a string) are handed over to T3.

1b) 创建 w 线程 T2 - 收集设备电池的使用百分比每隔 B 秒重复一次,并将结果(以字符串形式)交给 T3.

1b) create w thread T2 - the percentage usage of the device's battery is collected repeatedly every B seconds, and the results (as a string) are handed over to T3.

1c) 在线程 T3 中,来自 T1 和 T2 的数据应存储在数组中,并在有超过 x 个数据时执行此操作.

1c) In Thread T3 data from T1 and T2 should be stored in array and do sth when there is more then x data.

  1. 停止按钮 - 停止所有三个线程

我是 iOS 线程的菜鸟.

I am a total noob in iOS threading.

  1. 你怎么看,我应该用什么 - DCG 就像这里:DCG 嵌入 DispatchWorkItem

我应该在 ViewController 中创建线程吗?或者我应该在模型部件中构建一种线程管理器?

Should i create a threads in ViewController? Or maybe i should build kind of a threading manager in a model part ?

如何在线程之间进行通信 - 我应该在 T3 中创建一种侦听器吗?

How to communicate between threads - should i create a kind of listener in T3?

现在我有这样的东西,但它不起作用.

By now i have sth like this, but it doesn't work.

 class ViewController: UIViewController, CLLocationManagerDelegate {  

 var threadLocalication: Thread?

 override func viewDidLoad() {
     super.viewDidLoad()

     self.threadLocalication = Thread.init(target: self, selector: #selector(getLocalization), object: nil)

     locationManager.delegate = self
     locationManager.requestAlwaysAuthorization()

 }

 @objc func getLocalization() {
     print("I am here")

     let timerLocalication = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: true) { timer in
         print("timer after 3 seconds")      //NOTHING IS PRINTED after thread starts
     }

 }

 @IBAction func startButtonPressed(_ sender: UIButton) {
     threadLocalication?.start()
 }
 @IBAction func stopButtonPressed(_ sender: UIButton) {
     threadLocalication?.cancel()
 }
}

为什么线程开始后什么都不打印?

Why nothing is printed after thread start?

请提出这 4 个问题,并给我任何建议(有什么问题)以及更一般的 - 我应该怎么做?

Please ask these 4 questions, and give me any advice (what is wrong) and more generally - How Should i do this?

推荐答案

对您问题的简短回答是不要以这种方式使用 Thread".(稍微长一点)的答案是 Timers 依赖于 RunLoops,并且您创建了一个没有 RunLoop 的线程,并且您在创建线程后立即销毁了它.但是无论如何您都不应该以这种方式使用 Thread.实际上,您几乎不应该在 iOS 开发中使用 Thread.

The short answer to your question is "don't use Thread this way." The (very slightly) longer answer is that Timers rely on RunLoops and you've created a Thread that has no RunLoop, and also you've destroyed your thread as soon as you created it. But you shouldn't use Thread this way anyway. In fact you should almost never use Thread in iOS development.

您描述的问题不需要这样的东西.但是,如果您发现某些您认为确实需要线程的内容,请先阅读 Apple 的 从线程迁移.

The problems you've described don't need anything like this. But if you find something where you think you really do need a Thread, first read Apple's Migrating Away From Threads.

如果最后你真的需要一个线程,那么你需要研究 线程.这里几乎每一行代码都是不正确的,所以与其全部改正,不如先阅读文档,然后提出一个新问题.这不是您启动线程的方式,也不是您停止线程的方式,也不是计时器的工作方式.(API 并不明显,所以我理解你为什么这样写.这根本不是你想要的.)

If in the end you really did need a Thread, then you need to study the docs for Thread. Almost every line of code here is incorrect, so rather than correct them all, start by reading the doc and then asking a new question. This isn't how you start a Thread, it isn't how you stop a Thread, and it isn't how Timers work. (The API is not obvious, so I understand why you wrote it this way. It's just not what you want at all.)

按照您描述的方式更新位置应该只通过响应位置管理器的委托回调来处理.如果您真的需要定期检查,那么您只需使用标准计时器即可.不需要 DispatchQueues、Threads 或其他任何东西.计时器完成所有工作(它使用 RunLoop).

Updating location the way you've described should just be handled by responding to the delegate callbacks from the location manager. If you really needed check periodically, then you'd just use a standard Timer. There's no need for DispatchQueues, Threads, or anything else. Timer does all the work (it uses a RunLoop).

同样,电池监控也不应该用定时器来完成.您想打开 UIDevice.isBatteryMonitoringEnabled 然后收听通知.如果您需要轮询,那么您只需要一个简单的计时器即可.

Similarly, battery monitoring should not be done with Timers. You want to turn on UIDevice.isBatteryMonitoringEnabled and then listen for notifications. If you needed to poll, then again, a simple Timer is all you need.

只要有可能,您就希望在情况发生变化时让系统呼叫您.如果你发现自己在投票,你通常做错了什么.但当你确实需要轮询时,Timer 是最常用、最简单的工具.

Whenever possible, you want to let the system call you when things change. If you find yourself polling something, you're usually doing something wrong. But when you really do need to poll, Timer is the most common and simplest tool.

这篇关于如何使用 Swift 在自定义线程中运行计时器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆