Search code examples
iosobjective-c-blocksrunloop

What is the block that CFRunLoopPerformBlock() handles?


I'm currently learning the runloop mechanism in iOS. After reading Run, RunLoop, Run! and the CFRunloop source code, I'm still confused about how it really works. One of my confusions is about the CFRunLoopPerformBlock() function. Many articles mentioned that this function will enqueue the block and execute it in the next runloop, but my question is: what does the block mean here?

Let's say I have a very simple CustomViewController.

- (void)viewDidLoad
{
    [super viewDidLoad];
    UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(0, 50, 100, 100)];
    redView.backgroundColor = [UIColor redColor];
    [self.view addSubview:redView];
}

Apparently there's no block syntax in this code. Will viewDidLoad be called by CFRunLoopPerformBlock() ? If not, how is this snippet handled by runloop?


Solution

  • Apparently there's no block syntax in this code. Will viewDidLoad be called by CFRunLoopPerformBlock()? If not, how is this snippet handled by runloop?

    The viewDidLoad has practically nothing to do with CFRunLoopPerformBlock. The viewDidLoad is just a method that is called in our view controller when the view has been loaded, but before it’s been presented in the UI, to give us a chance to configure our UI.

    So what is the run loop? It is just a loop that is constantly running, checking for various events (events, timers, etc.). It’s running behind the scenes in every iOS app, though we rarely interact directly with it nowadays. (The exception might be when we start certain types of timers, we add them to the main run loop. But that’s about it nowadays.) But when we return from methods like viewDidLoad, we’re yielding control back to the run loop.

    what does the block mean here?

    A “block” (also known as a “closure” in Swift) is just a piece of code to be run, when this code block is stored in a variable or used as a parameter of a method. The CFRunLoopPerformBlock function effectively says, “here is a some code to run during the next iteration of the run loop”. The third parameter of that function is the code to be run, and is the “block” of code (in Objective-C it starts with ^{ and ends with the final }). For information about Objective-C blocks, see Apple's Blocks Programming Topics or Programming with Objective-C: Working with Blocks.

    All of this having been said, it’s worth noting that one wouldn’t generally use CFRunLoopPerformBlock. If we want to dispatch a piece of code to be run, we’d generally now use Grand Central Dispatch (GCD). For example, here is some code that has two parameters, a queue and a block:

    dispatch_async(dispatch_get_main_queue(), ^{
        self.label.text = @"Done";
    });
    

    Again, everything from the ^{ to the } is part of that second parameter, which is the block. This code says “add this block of code that updates the text of the label to the main queue.”