Reputation: 47
I am doing meta-programming with objective-C and try to automate some of an application functions. Thus, I am not changing the source code files and the view controllers of the application but from another file I am managing to get the UI navigation stack and I am using Objective-C Runtime Reference to find the tappable UI elements and the actions. for example for a button I found the target and action and call objc_msgSend to programatically fire the event.
step = (NSObject *)objc_msgSend(element.target, NSSelectorFromString(element.action));
However I need to be notified when the action was done, or in other word, I need to wait until the action was done and then continue my automation. I was thinking of using NSNotificationCenter
//To raise an event [[NSNotificationCenter defaultCenter] postNotificationName:FIRE_EVENT_NOTIFICATION object:self];
but doesn't look like working.
I am even thinking of using Categories or So I am not sure if there is anyway to wait for objc_msgSend and where should I continue.
Upvotes: 1
Views: 326
Reputation: 8345
It isn't entirely clear what you are trying to do and the exact problem that you are having but I'll have a go at answering your question.
If I understand correctly you are trying to fire the action associated with a UI element, presumably something like a button press. You have a reference to the element in element
and you want to call the associated action
on the elements target
. The following assumes the action is an IBAction
.
The simplest way to do this would presumably be:
[element.target performSelector:element.action];
Note: element.action
almost certainly returns a SEL
(a selector) not an NSString
so there is no need to run it through NSSelectorFromString()
.
Normally, an IBAction
event would receive the clicked on element as a parameter so I think you might want to do:
[element.target performSelector:element.action withObject:element];
IBAction
's have no return value so there is nothing to store when the method returns.
performSelector:
and performSelector:withObject:
will only return once the called method has run to completion. You shouldn't need to organise some sort of notification of the action completing.
However, if the action you are calling is launching code on another thread then it is possible that the called action will return before the result of pressing the button has completed. This will be difficult to monitor without knowledge of the code that is being run.
If, for some reason, you have to use objc_msgSend
then you would use the following:
objc_msgSend(element.target, element.action, element);
Like performSelector:
, objc_msgSend
will only return when the called method has run to completion.
Hopefully I have understood your question and my answer makes sense, it is entirely possible I'm barking up the wrong tree though.
Upvotes: 1