In the code that I show below, I have created a thread that creates random numbers between 0 to 15, and it stops when it comes out 3, changing the end parameter. After I added a run loop observer (that "observe" the end parameter) to the run loop of the main thread. As you can see, both the run loop observer and my thread, sleep for 1 second before printing, so I expect that in the console, observer's print and the print of my thread is alternate. Which is not the case. I believe, if I understand it, it would depend on CFrunloopActivity
parameter and its possible combinations.
Does anyone can explain the operation of this parameter? If yes, there is a combination to have alternating prints? If you can not have alternating prints, how does the observer work inside the run loop of the main thread ?
Thank you
This is the code :
class ViewController: UIViewController {
var end = false
override func viewDidLoad() {
super.viewDidLoad()
//my thread
performSelector(inBackground: #selector(rununtil3(thread:)), with: Thread.current)
//the observer
let runLoopObserver = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, CFRunLoopActivity.entry.rawValue | CFRunLoopActivity.exit.rawValue , true , 0 , {
(observer: CFRunLoopObserver?, activity: CFRunLoopActivity) -> Void in
Thread.sleep(until: Date(timeIntervalSinceNow: 1))
print("+++ is main?: \(Thread.isMainThread)")
if self.end == true {
//print the end of my thread and remove the observer from main run loop
print("end of own thread")
CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), observer, CFRunLoopMode.commonModes)
return
}
//CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), observer, CFRunLoopMode.commonModes)
})
//add observer to main run loop
CFRunLoopAddObserver(CFRunLoopGetCurrent(), runLoopObserver, CFRunLoopMode.commonModes)
print("Out of observer")
}
func rununtil3(thread : Thread) {
print("main?: \(thread.isMainThread) is run : \(thread.isExecuting)")
while true {
let ran = Int (arc4random() % 15 )
Thread.sleep(until: Date(timeIntervalSinceNow: 1))
print("\(ran) . main is run : \(thread.isExecuting)")
if ran == 3 {
end = true
Thread.exit()
}
}
}
}