2

For example, to call authenticateHandler

@property(nonatomic, copy) void(^authenticateHandler)(UIViewController *viewController, NSError *error)

The little hat thing ^(UIViewController *viewController, NSError *error) indicates the call should have an anonymous function block:

[lp setAuthenticateHandler:(^( UIViewController* vc, NSError *nsError )
  {
    if( !nsError )
    {
      puts( "GC auth success" ) ;
    }
  })];

But Say I want that function i'm using in my call to setAuthenticateHandler to be a named function. Other places I've seen use of @selector(functionName), but that doesn't seem to work here.

bobobobo
  • 64,917
  • 62
  • 258
  • 363
  • You would need to supply a block. Nothing stopping you from calling your named within the block. – Jeremy Mar 29 '13 at 05:45
  • Actually the pattern looks like `__weak YourClassName* weakSelf = self; [lp setAuthenticateHandler:(^( UIViewController* vc, NSError *nsError ) { if( !nsError ) { [weakSelf gcPlayerLoggedInSuccess];}` You need the `__weak` ptr due to the [capturing self strongly in this block is likely to lead to a retain cycle](http://stackoverflow.com/questions/14556605/capturing-self-strongly-in-this-block-is-likely-to-lead-to-a-retain-cycle) problem – bobobobo Mar 29 '13 at 06:31

2 Answers2

1

Blocks, selectors, and function pointers (not sure which of the latter two you're referring to as named functions) are all incompatible types so you cannot pass one where an argument of a another type is expected. Fortunately, if you do need to use function pointers or selectors with a block-based API, it's very easy to do so. Blocks will capture function pointers and selectors that are in scope at the time of their creation and you can use them within the block (just as they do with any other variable). For example, the following view controller provides wrappers to GCD (a block based API) that accept selectors or function pointers as arguments:

ViewController.h:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@end

ViewController.m:

#import "ViewController.h"

void callback() { NSLog(@"call back function"); }

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self doSomethingWithCompletionSelector:@selector(callback)];
//    [self doSomethingWithCompletionFunction:callback];

}

- (void)callback
{
    NSLog(@"call back selector");
}

- (void)doSomethingWithCompletionSelector:(SEL)selector
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ {
        NSLog(@"Doing something");
        // Causes a warning in ARC
        [self performSelector:selector];
    });
}

- (void)doSomethingWithCompletionFunction:(void (*)())function
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"Doing something");
        function();
    });
}

@end

And, of course, you can explicitly call any method or function and the receiver and arguments will all be captured by the block.

Carl Veazey
  • 18,392
  • 8
  • 66
  • 81
0

Selectors and blocks are completely different concepts.

A @selector(functionName) is of type SEL

A block is a C-level syntactic runtime feature, and in Objective-C, it's actually an object.

For more information on selectors check here.

For more information on blocks check here.

Community
  • 1
  • 1
Pedro Mancheno
  • 5,237
  • 4
  • 24
  • 31