how to make handler method run 1st in Objective-C - objective-c

In the below method calls from a single object, how to make the handler method to run 1st and then the main method in Objective-C?
Does it run in Asynchonous or Synchronous way?
Main method :AuthenticateMobileServer
handler Method :Handler
[mobile_Obj authenticateMobileServer:self action:#selector(handler:)];
Thank You.

I'm not sure if I'm getting what you're asking. But first of all please do use correct naming/capitalization for Objective-C! So please take a look at (http://developer.apple.com/mac/library/documentation/cocoa/conceptual/objectivec/articles/ocLanguageSummary.html)
(method names and variable names are in lowerCamelCase! Only class names are in CamelCase)
so it should be [mobileObj authenticateMobileServer:self action:#selector(handler:)]
Now to your question. By sending a authenticateMobileServer:action: message to mobileObj only that method is executed. #selector(handler:) is only a function pointer.

Related

SignalR-Objc Invoke Completion Handler Not Called

I am trying to use the completion handler on invoke to perform certain actions once the hub has return a result. Im using the following line currently:
myHub invoke:#"stpm" withArgs:messageParam completionHandler:^(SRHubResult *hubResult) {
NSLog(#"Complete");
}
But the block is never called. The invoke still works fine but the block never gets used. Any suggestions as to why?
I can only spot 1.5 issues with your snippet, completionHandler returns either NSDictionary, NSArray, NSNumber, or NSString. Also, is messageParam array?
I have found the issue. In SRHubProxy.m when the method send is called from SRHubProxy.m in invoke, the line:
[_connection send:hubData];
is wrong. The block never gets passed whether you have declared one or not. I changed it to:
[_connection send:hubData completionHandler:block];
which now passes the block correctly and it seems to work.

Is there something about this method name that indicates it's asynchronous?

I've inferred what a lot of things DO in Objective-C, and I've gone through several tutorials that simply talk about the data types, but I haven't run across anything that simply explains the syntax.
For starters, what does this mean? What it does is start a thread and get data returned from a server:
- (void)apiCall:(void (^)(NSMutableArray *list))block {
Does something in that function header tell me that it is asynchronous? is that what block means?
No, block doesn't mean asynchronous, a block in Obj-C is just a bit of code that can be passed as an argument to a method.
methods that start with - are instance methods and those that start with + are class methods.
^ is a syntactic marker to denote a block.
For your first question: you would have to look at the API documentation to find out if it is asynchronous.
For more information about blocks in general, see here:
Apple Blocks Programming Guide
Let's start with your second bullet:
Class methods are declared with +, instance methods are declared with -.
The first and third are related, the parameter named block is a code block, it's a piece of code intended to be run later. Given the name of this method apiCall, I suggest this being the method run after the call is done.
It would we natural to suspect that this method will do some work on another thread and then invoke the block you supplied, but for this you'd need to check the documentation or the code.
The signature: (void (^)(NSMutableArray* list)) block describes a code block with a void return type and a NSMutableArray* list as only parameter.
An example usage of the block parameter would be:
void (^apiCallCallback)(NSMutableArray*) = ^(NSMutableArray* list) {
NSLog(#"The API returned %d items in a list", [list length]);
}
[someApiInstance apiCall:apiCallCallback];
After the API instance is done doing whatever it is suppose to do, you'll see that the log statement is printed.

How to create an NSInvocation from a called method implementation?

I have a function that looks like this:
void myMethodImpl(id self, SEL _cmd, ...)
I use this as a implementation for a method on a class
class_addMethod(aClass, aSelector, (IMP)myMethodImpl, types);
so myMethodImpl get's called when a message is sent to aClass with selector aSelector. Now there I'd like to create an NSInvocation with all parameters from myMethodImpl.
Is there an easy way to create a NSInvocation from the parameter list or do I have to check every element for it's type and add it accordingly?
Since you're adding a method to the class, why not add/swizzle forwardInvocation: instead? At that point the runtime will have nicely built an invocation for you.
This is not possible. A simple google search shows this article:
http://www.wincent.com/a/about/wincent/weblog/archives/2006/03/nsinvocation_an.php
Which clearly explains how va_args don't properly work with NSInvocation.
It is possible, indeed. Have a look to the actionSelectorImplementation function in https://github.com/rlopezdiez/TMInstanceMethodSwizzler/blob/master/Classes/TMInstanceMethodSwizzler.m

Objective-C Selector pointer to be passed to a C function

I have a C struct that contains a function pointer. Now, I have used this setup within C with no problems, but now I'm using this C struct in Objective-C and I need to pass a function (or selector) pointer that is defined in the Objective-C class.
1. Here is what I have for the Objective-C selector that needs to be passed as a pointer to the C function:
- (void)myObjCSelector:(int*)myIntArray
{
// Do whatever I need with myIntArray
}
2. And here is where I run into a wall, Within Objective-C I'm trying to pass the selector as a pointer to the C function call: In place of "myObjCSelectorPointer" I need the proper syntax to pass the selector as a function pointer in this C function call:
passObjCSelectorPointerToCContext(cContextReference, myObjCSelectorPointer);
I did investigate this issue, but could mainly find several different ways of doing similar things, but I couldn't find anything specific for calling C functions and passing an Objective-C selector pointer.
In objc a selector is not a function pointer. A selector is a unique integer that is mapped to a string in a method lookup table stored by the objc runtime. In the above case your method name would be myObjCSelector: and to get the unique selector for it you would type #selector(myObjCSelector:). However this would be of no use to you because it doesnt represent a particular implementation of a function.
What youre looking for is IMP. Refer to this SO question.
EDIT 2:
IMP myObjCSelectorPointer = (void (*)(id,SEL,int*))[self methodForSelector:#selector(myObjCSelector:)];
Then you can call the method using
myObjCSelectorPointer(self,#selector(myObjCSelector:),myIntArray);
However, what this means you will need to make sure that you add the pointer to self in the c function call passObjCSelectorPointerToCContext.
So it should look like this
passObjCSelectorPointerToCContext(cContextReference, self, myObjCSelectorPointer);
when called from within the object that contains the method.
It is important to note though that using IMP is almost never the right technique. You should try to stick with pure Obj-C. Obj-C is quite efficient after the first call to a message because it uses temporal caching.
EDIT 1:
It's useful to understand why objc works in this way. The Apple documents explain it in depth. However a short explanation is as follows:
When you send a message to an object such as [myobject somemethod] the compiler won't immediately know which particular implementation of somemethod to call because there might be multiple classes with multiple overriden versions of somemethod. All of those methods have the same selector, irrespective of its arguments and return values and hence the decision about which implementation of somemethod is deffered to when the program is running. [myobject somemethod] gets converted by the compiler into a C function call:
objc_msgSend(myobject, #selector(somemethod))
This is a special function that searches each myobject class layout to see whether that class knows how to respond to a somemethod message. If not it then searches that class's parent and so on until the root. If none of the classes can respond to somemethod then NSObject defines a private method called forward where all unknown messages are sent.
Assuming that a class can respond to the somemethod message then it will also have a particular pointer of type IMP that points to the actual implementation of the method. At that point the method will be called.
There is considerably more to this procedure than I have described but the outline should be enough to help you understand what the goal of a selector is.
One final point is that the reason method names are mapped to unique integers via the #selector directive is so that the runtime doesn't have to waste time doing string comparisons.
Basically, the answer is: Objective-C selectors are different from function pointers. You need two pieces of data to perform a selector. That is an object and the selector itself. You will need some glue to accomplish your task.
Check this question.
Do you have to use a function pointer? In Objective-C, you can get the function pointer to an arbitrary method implementation (known as an IMP), but this is extremely uncommon, and usually not a good idea. Calling objc_msgSend() directly is also not the greatest idea, because there are several different variants of objc_msgSend(), and the compiler automatically chooses different ones to use based on the return type of the method. Methods that return an object go through objc_msgSend(), but objects that return structs might go through objc_msgSend() or they might go through objc_msgSend_stret(). And if the method returns a double, then it goes through objc_msgSend_fpret()...
Documentation: Objective-C Runtime Reference: Sending Messages
Instead, I might recommend using a target-action pair, or using a block. Then you might do something like:
myContextRef->target = anObjcObject;
myContextRef->action = #selector(invokeMe:);
And when you're done, do:
[myContextRef->target performSelector:myContextRef->action withObject:someReturnInformation];
Or maybe use a block:
myContextRef->completionHandler = [^(id returnInformation) {
[anObjcObject invokeMe:returnInformation];
} copy];
And then when you're done, do:
myContextRef->completionHandler(someReturnInformation);
(and don't forget to -release the block when you free the context)

Objective-C va_list and selectors

Is it possible to use #selector and performSelector: (or similar) with methods using variable arguments list?
I'm writing a class that can be assigned a delegate to override the default behavior. In the presence of a delegate select method calls made on an instance of that class will be forward to the same corresponding delegate method, some which use variable argument lists.
So, for instance, I need to be able to create retrieve SEL reference and message the delegate object with a method such as this:
- (void)logEventWithFormat:(NSString *)format, ... {
va_list argList;
id del = self.delegate;
if (del != nil &&
[del conformsToProtocol:#protocol(AProtocolWithOptionalMethods)] &&
[del respondsToSelector:#selector(logEventWithFormat:)])
{
// Perform selector on object 'del' with 'argList'
}
}
I am assuming this is not possible, hence the similar method declaration in the Foundation framework - in NSString:
- (id)initWithFormat:(NSString*)format, ...;
and
- (id)initWithFormat:(NSString *)format arguments:(va_list)argList;
I assume that the protocol I wish to delegate to should suggest the implementation of:
- (void)logEventWithFormat:(NSString *)format arguments:(va_list)argList;
so I the selector #selector(logEventWithFormat:arguments:) can be used an called with:
[del performSelector:#selector(logEventWithFormat:arguments:)
withObject:format
withObject:argList];
I just wondered if I was missing something or going the long way around to achieve what I'm trying to?
You can pass anything you want into the runtime function objc_msgSend.
objc_msgSend(del, #selector(logEventWithFormat:arguments:), format, argList);
It's the most powerful way of sending a manually constructed message.
However, it's not clear that you need to perform the invocation this way. As KennyTM pointed out, in the code you have, you could invoke the method directly.
You can't use -performSelector:withObject:withObject: because va_list simply isn't an "object". You need to use NSInvocation.
Or simply call
[del logEventWithFormat:format arguments:argList];
As far as I know, it can't be done. You can't use -performSelector:withObject:withObject: because as #KennyTM points out, a va_list isn't an object.
However, you also cannot use NSInvocation. The documentation straight up says so:
NSInvocation does not support
invocations of methods with either
variable numbers of arguments or union
arguments.
Since these are the two ways of invoking a method by selector, and neither seems to work, I'm going to go with the "can't be done" answer, unless you invoke the method directly and pass the va_list as an argument.
Perhaps #bbum will show up and enlighten us further. =)
I haven't done it that way before, but the simple solution I've often used is to box/unbox either an NSMutableArray or an NSMutableDictionary for the withObject parameter.