I have searched but cannot find an example of this.
In my example I use playground to nest for-loops in a function called from within DispatchQueue.
I find many roadblocks:
//import AppKit // playground doesn't recognize AppKit?!
import Dispatch
import Foundation
var comboCount:NSKeyValueObservation?
//class viewContr: NSViewController {
@IBOutlet weak var progressBar: NSProgressIndicator!
// deinit { comboCount?.invalidate() }
@IBAction func calcStuff() {
DispatchQueue.global(qos: .userInitiated).async {
let combos = possibleCombos()
DispatchQueue.main.async {
for word in combos {
word.print0b8()
}
}
}
}
//}
func possibleCombos() -> [Int8] {
var combos = [Int8]()
for a in [0, 1] {
for b in [0, 1] {
for c in [0, 1] {
for d in [0, 1] {
combos.append(Int8(d | (c << 1) | (b << 2) | (a << 3)) )
comboCount = combos.count/16 as! NSKeyValueObservation
// known total combos = 16
// How do I pass combos.count out to a progress bar?
}
}
}
}
return combos
}
extension Int8 {func print0b8() {print("0b" + pad(string: String(self, radix: 2), toSize: 4))}}
func pad(string : String, toSize: Int) -> String {var padded = string;for _ in 0..<(toSize - string.count) {padded = "0" + padded};return padded}
Removing the @IB obstacles and the attempted declaration of a ViewController does produce output, but can't be used with a progress bar, e.g.,
import Dispatch
import Foundation
DispatchQueue.global(qos: .userInitiated).async {
let combos = possibleCombos()
DispatchQueue.main.async {
for word in combos {
word.print0b8()
}
}
}
func possibleCombos() -> [Int8] {
var combos = [Int8]()
for a in [0, 1] {
for b in [0, 1] {
for c in [0, 1] {
for d in [0, 1] {
combos.append(Int8(d | (c << 1) | (b << 2) | (a << 3)) )
// known total combos = 16
// How do I pass combos.count out to a progress bar?
}
}
}
}
return combos
}
extension Int8 {func print0b8() {print("0b" + pad(string: String(self, radix: 2), toSize: 4))}}
func pad(string : String, toSize: Int) -> String {var padded = string;for _ in 0..<(toSize - string.count) {padded = "0" + padded};return padded}
In my actual App, i.e., not this playground, I have a ProgressBar in my storyboard and an IBoutlet declared in my view controller. I just can't find how to pass a value out of "possibleCombos()" and into the NSProgressIndicator.
What I have read suggests a delegate but reading about delegates hasn't helped. I need an example.
Thanks.
This now works. No more dispatch in calc.
For sure, code could be improved, but that's a way to get it working.
class viewContr: NSViewController {
var comboCount: Int = 0 // NSKeyValueObservation?
var when = DispatchTime.now()
@IBOutlet weak var progressBar: NSProgressIndicator!
@IBAction func calcStuff(_ sender: NSButton) {
DispatchQueue.global(qos: .userInitiated).async {[self] in
let combos = possibleCombos()
// DispatchQueue.main.asyncAfter(deadline: when) {
for word in combos {
word.print0b8()
}
// }
}
}
func possibleCombos() -> [Int8] {
var combos = [Int8] ()
var combosForDisplay = combos // That's the way to get value both for return and for progress
when = DispatchTime.now()
for a in [0, 1] {
for b in [0, 1] {
for c in [0, 1] {
for d in [0, 1] {
let value = Int8(d | (c << 1) | (b << 2) | (a << 3))
combos.append(value )
DispatchQueue.global().asyncAfter(deadline: when) {[self] in
combosForDisplay.append(value) // Do it again ; otherwise we capture the wrong value from combos
comboCount = (100 * combosForDisplay.count) / 16 // as! NSKeyValueObservation
print(comboCount, when)
DispatchQueue.main.async { [self] in
progressBar.doubleValue = Double(comboCount)
}
// known total combos = 16
// How do I pass combos.count out to a progress bar?
}
when = when + .milliseconds(300)
}
}
}
}
return combos
}
}
extension Int8 {func print0b8() {print("0b" + pad(string: String(self, radix: 2), toSize: 4))}}
func pad(string : String, toSize: Int) -> String {var padded = string;for _ in 0..<(toSize - string.count) {padded = "0" + padded};return padded}