10

All events and methods in iOS are processed using NSRunLoop: user events, method calls, rotations, timers, connections, etc.

My question is:

How can I perform a selector in a precise moment of the run loop as the beginning and the end?

vilanovi
  • 2,097
  • 2
  • 21
  • 25

2 Answers2

24

You can create a CFRunLoopObserver which will call a block on loop entry and exit. You use CFRunLoopAddObserver to add your observer to the run loop, and CFRunLoopGetMain to obtain the run loop to add to.

Here is a rather pointless example using these:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
   CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(NULL, (kCFRunLoopEntry | kCFRunLoopExit), YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity)
   {
      static unsigned long count = 0;
      NSLog(@"activity %lu: %@", ++count, (activity & kCFRunLoopEntry ? @"Enter" : @"Exit"));
   });
   CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopCommonModes);
}

This simply installs an observer which logs every entry & exit to the run loop. You can run it as a complete application in Xcode and see how many times the run loop goes around.

Note that CFRunLoopObserverCreateWithHandler returns a reference you own, if you remove the observer you are responsible for deallocation.

CRD
  • 52,522
  • 5
  • 70
  • 86
0

I converted the accepted @CRD 's answer's code to Swift version.

let observerRef = CFRunLoopObserverCreateWithHandler(nil,  CFRunLoopActivity.entry.rawValue | CFRunLoopActivity.exit.rawValue, true, 0) { observer, activity in
    // Do something in RunLoop
}
CFRunLoopAddObserver(CFRunLoopGetMain(), observerRef, .commonModes)