问题
I have to make a simple task - singleview app with two buttons and three treads -
Start Button :
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.
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.
Data from T1 and T2 should be stored in array with limited positions (maxData). In Thread T3, if array reaches maxData data should be send to the server (URL) via HTTP. Then clear array
STOP button - just stop all three threads
I am a total noob in iOS threading. Unfortunately, App MUST use threads even if it is not necessary. In my previous question, Rob Napier suggested to use DispatchSourceTimers.
I'm close to find a proper solution, but sth is still wrong. When i clear array and post, single data from DispatchSourceTimer is LOST. I guess, that sth is wrong with concurrentDataQueue.async(flags: .barrier), and i have to block reading of array somehow (?)
Class BackgroundThreadTimer is just wrapper for DispatchSourceTimers taken from medium article(RepeatingTimer)
//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()
Could sb help? Is my diagnosis proper? And how to fix this.
回答1:
In appendAndPost
, you are appending result only if the count is less than maxData
.
But let’s imagine that you called this where you already had five items in the array. In that scenario, you start the request, but you’re never doing anything with the supplied value.
I would advise appending the value regardless, and sending if the count
hits the threshold:
func appendAndPost(phoneInfo: String) {
data.append(phoneInfo)
if data.count >= maxData {
// create your request and send it
...
// reset `data`
data = []
}
}
来源:https://stackoverflow.com/questions/64670183/multithread-task-threads-in-viewcontroller