0

I want the AppDelegate to perform the selector if it is possible, here is my code:

func RunLoopSourceScheduleRoutine(info:UnsafeMutableRawPointer?,r1:CFRunLoop?,mode:CFRunLoopMode?)->Void{

    let obj :  RunLoopSource = Unmanaged<RunLoopSource>.fromOpaque(info!).takeUnretainedValue()
    let theContext = RunLoopContext.init(initWithSource: obj, andLoop: r1!)

    let del = UIApplication.shared.delegate

    del.performSelector(onMainThread: #selector(removeSource), with: theContext, waitUntilDone: false)

}  

I've tried this :(The App crashes)

 AppDelegate.performSelector(onMainThread: #selector(removeSource), with: theContext, waitUntilDone: false)

How to perform a selector on the main thread from a global function?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Shadi Asi
  • 157
  • 13

3 Answers3

1

performSelectorOnMainThread:withObject:waitUntilDone: queues the message with common run loop modes. According to Apple's "Concurrency Programming Guide", the main queue will interleave queued tasks with other events from the app's run loop. Thus, if there are other events to be processed in the event queue, the queued blocks in the dispatch queue may be run first, even though they were submitted later.

To resolve the issue you can use dispatchQueue for this as follows:

DispatchQueue.main.async {
   UIApplication.shared.delegate.removeSource()
}

You can read more about this on following link: https://blackpixel.com/writing/2013/11/performselectoronmainthread-vs-dispatch-async.html

iOS_MIB
  • 1,885
  • 13
  • 24
0

Do like following way in swift 4:

performSelector(onMainThread: #selector(self.removeSource), with: nil, waitUntilDone: false)

@objc func removeSource() {
        print("removeSource")
    }
  • there is no performSelector implementation in a global function(a free function which not belong to a class) – Shadi Asi Feb 06 '18 at 12:15
  • @ShadiAsi see my answer here https://stackoverflow.com/a/43714950/5329717 However for your main problem IOS_MIB 's answer is definitely good enough. – Kamil.S Feb 10 '18 at 21:15
0

Instead of playing with selectors you can just wrap the content of removeSource in DispatchQueue.main.sync or DispatchQueue.main.async

class func removeSource() {
    DispatchQueue.main.sync {
        // Your code  
    }
}

EDIT: then you can call your function like this AppDelegate.removeSource()

Ivan Nesterenko
  • 939
  • 1
  • 12
  • 23