-2

I want to write something like this:

- (int)someMethod:(SEL)theSelector {

    NSObjet *i = func(...);
    i = theSelector(i); //replace this
    i = func2(...);
    return i;
}

So I have some constant functions I know and can simply write. I also have an undefined function which I should pass as a param.

I can't use constructions like performSelector: because they are even performed in another NSRunLoop cycle.

And I can't pass blocks to this function because of specific code.

How to solve this issue? It seems objc_msgSend may help but I don't know how to use it correctly.

Gargo
  • 1,135
  • 1
  • 10
  • 21
  • possible duplicate of [How to I pass @selector as a parameter?](http://stackoverflow.com/questions/932801/how-to-i-pass-selector-as-a-parameter) – thierryb Aug 22 '14 at 19:29
  • 1
    You should re-read the documentation. `performSelector:` is equivalent to calling the method directly, but is useful in cases such as yours where you don't know the exact selector ahead of time. It does not delay invocation until the next iteration of the run loop. If it did, it could not return a value since it would be undefined. – Steve Madsen Aug 22 '14 at 19:31
  • OMG. How to pass selector as parameter?! I have already passed it. Buy glasses if you don't see it. – Gargo Aug 22 '14 at 19:31
  • to Steve Madsen, I know that `performSelector:` is not an equivalent of a direct call because it doesn't return a result before the next string of code. Or is `performSelector:` differs from `performSelector:...afterDelay:`? – Gargo Aug 22 '14 at 19:34
  • to thierryb, delete your silly mark "possible duplicate". If you can't understand then read the following. You gived me a link about how to pass a method into another method only. BUT I have already passed it and ask about how to use it. So it is your link totally useless – Gargo Aug 22 '14 at 19:42

2 Answers2

1

Use NSInvocation. Here is a sample code.

NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: [[target class] instanceMethodSignatureForSelector:theSelector]];
[invocation setSelector:theSelector];
[invocation setTarget:target];
[invocation setArgument:&blockUserInfo atIndex:2]; // Argument 2 is the first argument in an NSInvocation, arg0 is 'self' and arg1 is '_cmd'.
[invocation invoke];
[invocation getReturnValue:&success];

Hope this helps.

Thierry

thierryb
  • 3,660
  • 4
  • 42
  • 58
  • Sorry, I can't check it today. Is it returns a value at once as if I call this function directly? – Gargo Aug 22 '14 at 19:37
0

First of all, a selector is just a method name. You need an object to send it to. I will assume it is self.

The simplest thing in this case is to use performSelector:onObject: (since it's a method that takes one object pointer argument):

i = [self performSelector:theSelector withObject:i];

This is the same as a direct method call (except for the overhead of the performSelector call itself). It does not do it asynchronously or after a delay or anything; you are confused.

If you want to know how to do it via objc_msgSend():

id (*func)(id, SEL, id) = (id (*)(id, SEL, id))objc_msgSend;
i = func(self, theSelector, i);

Note that you must first cast objc_msgSend to a function pointer type matching the underlying implementing function (which have two hidden parameters at the beginning, self; and _cmd, the selector). This will be completely identical to a direct method call, at the machine code level. You can imagine this is what compilers compile message calls to.

newacct
  • 119,665
  • 29
  • 163
  • 224
  • first of all the selector is NOT A METHOD NAME. Read theory first. – Gargo Aug 23 '14 at 05:26
  • @Gargo: Umm, excuse me? Why don't you read you stuff first before spouting BS? A selector is a uniquified string, used exclusively as method names in Objective-C. – newacct Aug 23 '14 at 06:01
  • Yes, it is an unique identifier, a method name is NSStringFromSelector(theSelector). In database "name" and "identifier" mean various things too. – Gargo Aug 23 '14 at 06:18
  • @Gargo: In the Apple implementation, a selector is a pointer to the beginning of a null-terminated C string. In any case, the point of a selector is that there is only one selector with a given string. The string is the essence of what the selector is. – newacct Aug 23 '14 at 23:02