0

I've this method :

func stepThree() {
    operation = "prDatas"
    let entries = self.data.componentsSeparatedByString("|***|")
    total = entries.count
    for entry in entries {
        ++current
        dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {
            self.registerDB(entry)
        })
    }
    status.setProgress(Float(current/total), animated: true)
    finishAll()
}

I want to perform registerDB function and update my progressBar when complete. I tested several way but never succeed


EDIT 1

Implementing @Russell proposition, work perfectly, but calculating value inside dispatch_async block always result to 0

Is there an issue about operations and multithread ?

method :

func stepThree() {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
        var current = 0
        var total = 0
        self.operation = "prDatas"
        let entries = self.data.componentsSeparatedByString("|***|")
        total = entries.count
        for entry in entries {
            ++current
            self.registerDB(entry)
            dispatch_async(dispatch_get_main_queue(), {
                print("value of 'current' is :" + String(current))
                print("value of 'total' is :" + String(total))
                print("Result is : " + String(Float(current/total)))
                self.updateV(Float(current/total))
            })
        }
    })
}

Console output :

value of 'current' is :71
value of 'total' is :1328
Result is : 0.0
Khorwin
  • 445
  • 1
  • 9
  • 27
  • 1
    Float(current/total) is your problem - the calculation is done first - with integers - and then the result (which is always 0) is converted to a Float. I had the same issue in my solution, which is why I converted both parameters to floats first – Russell Apr 12 '16 at 13:02
  • It's work better, thanks again ! – Khorwin Apr 12 '16 at 13:36

1 Answers1

1

Your code will update the status bar immediately - so the job will not have finished.

You need to move the update so that it actually follows the registerDB function, and then you have to make the call on the main thread. Here's an example - using dummy functions instead of your function calls, so that I can ensure it works as expected

func stepThree()
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
        let total = 5 // test data for demo
        for entry in 0...total
        {
            // dummy function - just pause
            sleep(1)
            //self.registerDB(entry)

            // make UI update on main queue
            dispatch_async(dispatch_get_main_queue(),
            {
                self.setProgress(Float(entry)/Float(total))
            })
        }
    })
}

func setProgress(progress : Float)
{
    progressView.progress = progress
    lblProgress.text = String(format: "%0.2f", progress)
}
Russell
  • 5,436
  • 2
  • 19
  • 27
  • This doesn't work. i tested updating from a function called with performSelectorOnMainThread, now breakpoints show me that, function is called at the good time, update value of progressView but not visually... – Khorwin Apr 12 '16 at 08:06
  • I have updated the answer above, wrapping the whole of `stepThree` in a background task, and making main queue calls to update the UI from within it. – Russell Apr 12 '16 at 10:21
  • You right, it's work fine ! thanks for that. I encounter a problem regarding the value to progress, i updated my post. – Khorwin Apr 12 '16 at 12:25
  • 1
    cool, glad I could help. Remember - if you like the answer, mark it as correct :-) – Russell Apr 12 '16 at 13:02