Home > Software engineering >  Where is the specific implementation used in objective-c?
Where is the specific implementation used in objective-c?

Time:10-24

Hello everyone i am new to objective c. The following code is not mine. I am just trying to understand how it works. I have a ViewController that has this property in the .h file.

@property (nullable, nonatomic, copy) dispatch_block_t logHandler;

Inside the .m file the logHandler is called when a button is pressed with the following code.

- (IBAction)login:(id)sender {
    if (nil != self.logHandler) {
        self.logHandler();
    }
}

Then the logHandler is called which exists in another class NSObject file

inside the .h file

@interface LogFlow : NSObject<TheFlowController>

@end

and in .m file

- (UIViewController *)rootViewController {
    LogViewController *viewController = LogViewController.newInstance;
    
    viewController.logHandler = ^{
      
        
        UIViewController *logController = [self startNewLogFlow];
        [self.navigationController pushViewController:logController animated:YES];
    };
    return viewController;
}

I do not understand why the logHandler exists in another class and why it is called from this specific class, and how is it possible to call this code from another class without any import used? I am trying to understand when to use this kind of implementation and how to use it. Any help appreciated.

CodePudding user response:

The construct that you see in the rootViewController:

^{  
    UIViewController *logController = [self startNewLogFlow];
    [self.navigationController pushViewController:logController animated:YES];
};

This is what's known as a "Block" in Objective-C. You may find other references to it in other languages as an "anonymous function" or a "closure". Those names apply here as well.

This creates an object that is just a function, but the function doesn't have a name. You can also assign the unnamed function to variables and call it from the variable - which is what happens here. The anonymous function, the block, is assigned to the logHandler instance variable of the viewController object. Later some other code can call that function through the variable as you see in your login: example.

Here's a simpler block that is just plain Objective-C:

int squareFunction(int x) {
    return x * x;
}

void playWithSquares(void);
void playWithSquares(void) {
    int nine = squareFunction(3);
    int alsoNine = (^(int x){
        return x * x;
    })(3);
}

The declaration of squareFunction creates a named function that calculates the square of two integers.

You also see the the expression:

^(int x){
    return x * x;
};

This also creates a function that calculates the square of an integer, but it doesn't bind that function to a name. Since it has no name we call the function immediately by wrapping it in parenthesis and then passing it arguments (<anonymous function expression>)(3)

We could store the anonymous function in a variable:

    typedef int (^SquaresBlock)(int);
    SquaresBlock myBlock = ^(int x){
        return x * x;
    };

and then call it later using squaresBlock(3)

Blocks are very important in Cocoa's use of Objective-C so you should learn more about them.

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html

  • Related