我必须完成一个简单的任务-具有两个按钮和三个踏板的Singleview应用-
开始按钮:
创建线程T1-每3.0秒重复收集一次设备的GPS位置,然后将结果(作为字符串)移交给T3。
创建线程T2-每B秒重复收集一次设备电池的使用百分比,并将结果(作为字符串)移交给T3。
T1和T2中的数据应存储在位置有限(maxData)的数组中。 在线程T3中,如果数组达到maxData,则应通过HTTP将数据发送到服务器(URL)。然后清除数组
停止按钮-只需停止所有三个线程
我对iOS线程一无所知。不幸的是,即使没有必要,App也必须使用线程。在我的previous question中,Rob Napier建议使用DispatchSourceTimers。
我已经接近找到合适的解决方案,但是……仍然是错误的。当我清除数组并发布时,来自DispatchSourceTimer 的单个数据丢失了。我猜想 concurrentDataQueue.async(flags:.barrier)是错误的,我不得不以某种方式阻止读取数组(?)
BackgroundThreadTimer类只是DispatchSourceTimers的包装,该包装取自 medium article(重复计时器)
//partly Pseudocode
var counter = 0
var data = [String]()
var maxData = 5
var counterInt = 0
var concurrentDataQueue = DispatchQueue(label: "dataCleanAndPostQueue", attributes: .concurrent)
var timerLocalization = BackgroundThreadTimer(timeInterval: 2)
timerLocalization.eventHandler = {
//do sth and receive String x with actual localization
//...
concurrentDataQueue.async(flags: .barrier) {
appendAndPost(phoneInfo: String(counterInt) + ": " + x)
counterInt += 1
}
}
var timerBattery = BackgroundThreadTimer(timeInterval: 3)
timerBattery.eventHandler = {
//do sth and receive String x with actual battery level
//...
concurrentDataQueue.async(flags: .barrier) {
appendAndPost(phoneInfo: String(counterInt) + ": " + x)
counterInt += 1
}
}
func appendAndPost(phoneInfo: String) {
if data.count < maxData {
data.append(phoneInfo)
} else {
let arrayString = data.joined(separator: "; ")
DispatchQueue.global(qos: .background).async {
//post arrayString to http
print(arrayString)
}
data = [String]()
}
}
//when start pressed
timerLocalization.resume()
timerBattery.resume()
//when stop pressed
timerLocalization.suspend()
timerBattery.suspend()
某人可以帮忙吗?是我的 诊断正确吗?以及解决方法。
答案 0 :(得分:1)
在appendAndPost
中,仅当计数小于maxData
时才追加结果。
但是,让我们想象一下,如果您在数组中已经有五个项目的地方调用了这个函数。在这种情况下,您可以启动请求,但是您永远不会使用提供的值做任何事情。
我建议无论如何都附加值,并在count
达到阈值时发送:
func appendAndPost(phoneInfo: String) {
data.append(phoneInfo)
if data.count >= maxData {
// create your request and send it
...
// reset `data`
data = []
}
}