30

How do you pass one method as a parameter to another method? I'm doing this across classes.

Class A:

+ (void)theBigFunction:(?)func{
    // run the func here
}

Class B:

- (void)littleBFunction {
    NSLog(@"classB little function");
}

// somewhere else in the class
[ClassA theBigFunction:littleBFunction]

Class C:

- (void)littleCFunction {
    NSLog(@"classC little function");
}

// somewhere else in the class
[ClassA theBigFunction:littleCFunction]
bryanmac
  • 38,941
  • 11
  • 91
  • 99
Jacksonkr
  • 31,583
  • 39
  • 180
  • 284
  • 1
    You pass selectors, Here is a similar question: http://stackoverflow.com/questions/519600/is-it-possible-to-pass-a-method-as-an-argument-in-objective-c – utahwithak Oct 29 '11 at 02:00

4 Answers4

49

The type you are looking for is selector (SEL) and you get a method's selector like this:

SEL littleSelector = @selector(littleMethod);

If the method takes parameters, you just put : where they go, like this:

SEL littleSelector = @selector(littleMethodWithSomething:andSomethingElse:);

Also, methods are not really functions, they are used to send messages to specific class (when starting with +) or specific instance of it (when starting with -). Functions are C-type that doesn't really have a "target" like methods do.

Once you get a selector, you call that method on your target (be it class or instance) like this:

[target performSelector:someSelector];

A good example of this is UIControl's addTarget:action:forControlEvents: method you usually use when creating UIButton or some other control objects programmatically.

Filip Radelic
  • 26,607
  • 8
  • 71
  • 97
9

Another option is to look at blocks. It allows you to pass a block of code (a closure) around.

Here's a good write up on blocks:

http://pragmaticstudio.com/blog/2010/7/28/ios4-blocks-1

Here's the apple docs:

http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/00_Introduction.html

bryanmac
  • 38,941
  • 11
  • 91
  • 99
  • This should be accepted answer, as it is much more versatile. It also simplifies the case where passing arguments to the called method is dependent on context. – aclima Jul 01 '19 at 10:36
7

Objective C makes this operation relatively easy. Apple provides this documentation.

To directly address your question, you are not calling a function, but a selector. Here is some sample code:

Big Function:

+ (void)theBigFunction:(SEL)func fromObject:(id) object{
    [object preformSelector:func]
}

Then for class B:

- (void)littleBFunction {
    NSLog(@"classB little function");
}

// somewhere else in the class
[ClassA theBigFunction:@selector(littleBFunction) fromObject:self]

Then for class C:

- (void)littleCFunction {
    NSLog(@"classC little function");
}

// somewhere else in the class
[ClassA theBigFunction:@selector(littleCFunction) fromObject:self]

EDIT: Fix selectors sent (remove the semicolon)

MJD
  • 1,183
  • 7
  • 13
  • Your selectors don't match method descriptions, there shouldn't be any `:` at the end of them. – Filip Radelic Oct 29 '11 at 02:30
  • Oops, sorry about that. I'm not much of an objective c coder (I've only dabbled in it) and I followed Apple's examples too closely! – MJD Oct 29 '11 at 02:40
5

You can use Blocks for this purpose. http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/00_Introduction.html

ARC
  • 1,794
  • 2
  • 17
  • 21