Finding out which class is calling a function - iOS, objective C - objective-c

I have a function - myFunc() in class A. There are multiple other classes calling this function.
How will I be able to find out which class is calling myFunc() at a particular instance?
Would someone be able to help me with this?

Conceptually, this information is available in the stack, though it isn't easy to get to. Most solutions would involve creating an exception in order to capture the stack trace, and then reading the trace. I haven't tried this, but it might work:
void myFunc()
{
NSArray *stack = [NSThread callStackSymbols];
// I have no idea if the current function call is at the 0 or last position
// of the array. Experiment here!
}
Pertinent documentation: NSThread Class Reference
Note that if you want your function to behave differently depending on who is calling, DO NOT DO THIS. It's fragile (there are no guarantees about whether the format of what callStackSymbols returns will change).
It's better to simply pass a parameter into your function. If you're dealing with a C-function callback API, there is typically a void * "context" or "info" parameter that you can use to pass in an arbitrary pointer. This could be a pointer to your object.

Use the Visitor pattern
Have each of the calling classes implement a common protocol that defines the interface of the behavior you are looking to achieve.
Add the protocol as a parameter to myFunc.
When calling myFunc(), specify self as the parameter.
myFunc can now invoke any of the protocol methods without knowing about the other specific classes.
This way you adhere to the concepts of encapsulation.

Related

How does compiler know which function I want to use?

I defined two functions.They are all the same, except in different class. And I imported one class into another class, and then used #selector(functionName).How does compiler know which function I want to use?
A "selector" is the name of a function. The type is SEL, which is no more than a typedef to NSString*. The selector not the function implementation itself (which also exists, type IMP).
Therefore, you cannot execute a selector, because there is no code behind.
If you want to "call" a function thru a selector, you need to specify an instance on which you want the selector to be performed onto. The root class NSObject has several functions like performSelector, which will take the selector, look for the implementation in that object, and then execute that function implementation.
The magic behind is the Objective C runtime. In reality, it's a little more sophisticated than explained above; look for objc_msgSend if you are interested in more details.

Objective-C: when to use function vs method

I've started using Xcode's refactoring abilities (edit > refactor > extract) and noticed that Xcode offers to extract a method or a function.
I've read here and elsewhere about the differences between the two and understand that a method is connected to a class while a function is not. So I'm not looking for definitions, please.
Assuming that no arguments are involved, when is it appropriate to use one instead of the other? I understand that if something isn't really about the class then it could be a function but again, that's just about the definitions. I'm looking for good ol' use cases.
In my personal case, I'm trying to refactor some code out of the AppDelegate's applicationDidEnterBackground. As it is the only place to handle events upon entering the background, the only way to clean up the code is to extract subroutines into .. well, functions. But they'd be inside AppDelegate.m so wouldn't they be methods?
Hmmm..
Personally, I only use functions if, and only if, the following two requirements are met:
I use it so frequently within a given class, or throughout the project, that it warrants being generalized.
It has no side-effects or context dependancies (none of that void *context mess).
In my opinion, C-style functions should only be used as a last resort or in cases where you truly need functional behavior within this kind of an application. Event handling is both application-specific, and context sensitive, so it's best if you left that alone and focused on refactoring common patterns out.
You use functions when you have a, well, function ;-) You know the definitions: a method has an implicit argument self and can access instance variables using that; a function has no implicit arguments - everything it needs must be passed in.
If you are refactoring part of a larger method, that part does not access instance variables, and you are not refactoring it so that a subclass can override it, then let Xcode build you a function. When its done add static to it so it is private to the class.
In doing this you've lost nothing and made it clear that the piece of code is a function - it does not alter the state of the object.
There is of course no hard line between picking a function and a method, its a fuzzy boundary. If a piece of code, say, just accesses one or two instance variables but does not update them then you might pick a function - again making it clear that the object state is not being modified. But you don't want to pass lots of instance variables in as parameters, that is just hard to read (and inefficient).
Using functions can be good, and its certainly not bad to do so in Objective-C.
Method of a class usually need to access instance variables connected to that class. Functions in Objective-C are not connected to a class, and therefore have no access to any non-public member variables of classes.
Consider the class KNode, which contains member variable _memberVar.
#interface KNode : NSObject {
int _memberVar;
}
#end
Any method of this class could access and change the member variable, but any old function cannot, as it is private.
#implementation KNode
- (void)modify {
_memberVar = 10;
}
#end
The following function will not work
void modify(KNode * node) {
_memberVar = 10;
}
Two small but meaningful advantages of functions:
They can be internal-only by marking them static, or
__attribute__((visibility("hidden"))), which is helpful for framework developers
They can be inlined. For example, I use this pattern for fast lazy queue creation:
static inline dispatch_queue_t sharedQueue() {
static dispatch_queue_t queue;
static dispatch_once_t once;
dispatch_once(&once, ^{
queue = dispatch_queue_create("foo", 0);
});
return queue;
}

what was the second parameter in "id (*IMP)(id, SEL, ...) " used for?

my question as the title says.obviously, the first parameter was used for this pointer , in some taste of c++.what about the second one? thak you.
The signature of objc_msgSend() is:
id objc_msgSend(id self, SEL op, ...);
Every method call is compiled down to a call to this function. I.e., if you call:
[anArray objectAtIndex:42];
That will be compiled as if it were:
objc_msgSend(anArray, #selector(objectAtIndex:), 42);
Now, to your question, why do methods get compiled down to a function that has the SEL as the second argument. Or, more specifically, why is this method:
- (id)objectAtIndex:(NSUInteger)index;
Exactly equivalent to this C function:
id object_at_index(id object, SEL _cmd, NSUInteger index);
The answer is speed speed speed.
Speed
Specifically, by doing this, then objc_msgSend() never has to rewrite the stack frame* and it can also use a tail call optimization to jump directly to the method invocation. This is the same reason why you never see objc_msgSend() in backtraces in the debugger (save for when you actually crash/break in the messenger).
objc_msgSend() uses the object and the _cmd to look up the implementation of the method and then, quite literally, jumps to that implementation.
Very fast. Stack frame untouched.
And, as others have stated, having _cmd around in the method implementation can be handy for a variety of reasons. As well, it also means that the messenger can do neat tricks like proxy support via NSInvocation and the like.
*rewriting the stack frame can be insanely complex and expensive. Some of the arguments might be in registers some of the time, etc... All architecture dependent ABI nastiness. One of the biggest challenges to writing things like imp_implementationWithBlock() was figuring out how to do so without touching the stack because doing so would have been too slow and too bloated to be viable.
The purpose of having the second parameter contain the selector is to enable a common dispatch mechanism. As such, the method dispatch code always expects the second parameter to be the selector, and dispatches based on that, or follows the inheritance chain up, or even creates an NSInvocation and calls forwardInvocation:.
Generally, only system-level routines use the selector argument, although it's rather nice to have it when you hit an exception or are in the debugger trying to figure out what routine is giving you difficulties if you are using forwardInvocation
From the documentation:
Discussion
This data type is a pointer to the start of the function that implements the method. This function uses standard C calling conventions as implemented for the current CPU architecture. The first argument is a pointer to self (that is, the memory for the particular instance of this class, or, for a class method, a pointer to the metaclass). The second argument is the method selector. The method arguments follow.
In Objective-C when you call a method you need to know the target, the selector and the eventual arguments. Let's suppose that you are trying to do this manually: how can you know which method to call if you don't know the selector? Do you call some random method? No, you call the right method because you know the method name.

Is the use of header-less method implementations good practise or frowned upon?

If you write method implementations in Objective-C, it is pretty standard to sum up the methods of a class in the corresponding #interface blocks. Publically accessible methods go in the header file's interface, not-so-public methods can go in an empty category on top of the implementation file.
But it's not neccessary to declare an interface for every method. If you only reference the methods below their implementation code of the same class/file, there's no need to put any declaration anywhere else.
-(void) doSomething {
}
-(void) doSomethingElse {
[self doSomething];
}
Coming from another language, this is new to me. And I can't seem to decide whether it is nice and pretty to keep the interface blocks clean, or whether it should be prevented because the order of method implementations seem like a weird dependency to have.
What is the general public's opinion of this matter?
The general rule I follow is that if the only method calling doSomething is doSomethingElse then it's fine to not have doSomething be part of the declared private interface. But the moment a second method makes use of doSomething I add it to the declared interface.
The thinking behind this is that as long as the method is only ever called from one place there's no reason to think of it as modular or reusable code. Instead it's more like the method exists just to tidy up the implementation of its calling method. In essence, the method doesn't really stand on its own, so there's no point in treating it like an interface method. But as soon as a second method is making the same call it demonstrates that the code is in fact reusable and useful in more than just the original context, and able to stand on its own as a useful function. So at that point, it becomes a declared part of the private interface.
Some other coding style choices make answering this question really easy:
If you document every method at its declaration point, then not having a declaration means that either these methods are missing documentation, or they are documented at definition; either way it's inconsistent. If you follow the school of thought that most methods should be so self-explanatory from their name that they don't need documentation, this might not be an issue.
Some people advocate ordering methods from more general to more specific; in that model your example is ordered wrong, and the only way to fix it is to have a declaration.
There's also the question of whether you would find it annoying to get unexpected compiler errors when you do simple re-ordering or re-factoring just because you happened to start using a method earlier, and have to stop and add the declaration at that point.

Make NSInvocation invoke a specific IMP

I'm looking for a way to make an NSInvocation invoke a specific IMP. By default, it invokes the "lowest" IMP it can find (ie, the most-recently-overridden version), but I'm looking for a way to make it invoke an IMP from higher up in the inheritance chain. The IMP I want to invoke is determined dynamically, or else I'd be able to use the super keyword or something like that.
My thought was to use the -forwardInvocation: mechanism to capture a message (easy and already working) and then alter the IMP so it goes to a method that is neither the super implementation nor the furthest descendent's implementation. (hard)
The only thing I've found that comes remotely close is AspectObjectiveC, but that requires libffi, which makes it non-iOS compatible. Ideally I'd like this to be cross platform.
Any ideas?
disclaimer: i'm just experimenting
Trying out #bbum's idea of a trampoline function
So I think I've got things mostly set up; I've got the following trampoline that gets correctly added via class_addMethod(), and it does get entered:
id dd_trampolineFunction(id self, SEL _cmd, ...) {
IMP imp = [self retrieveTheProperIMP];
self = [self retrieveTheProperSelfObject];
asm(
"jmp %0\n"
:
: "r" (imp)
);
return nil; //to shut up the compiler
}
I've verified that both the proper self and the proper IMP are the right things prior to the JMP, and the _cmd parameter is also coming in properly. (in other words, I correctly added this method).
However, something is going on. I sometimes find myself jumping to a method (usually not the right one) with a nil self and _cmd. Other times I'll just crash in the middle of nowhere with an EXC_BAD_ACCESS. Ideas? (it's been a long time since I've done anything in assembly...) I'm testing this on x86_64.
NSInvocation is just an object representation of a message send. As such, it can't invoke a specific IMP any more than a normal message send could. In order to have an invocation call a specific IMP, you'd either need to write a custom NSInvocation class that goes through the IMP-calling routine or you'd have to write a trampoline that implements the behavior and then create an invocation that represents a message to the trampoline (i.e. you basically wouldn't be using NSInvocation for much of anything).
Added long after the fact, for reference:
You can do it with private API. Put this category somewhere convenient:
#interface NSInvocation (naughty)
-(void)invokeUsingIMP:(IMP)imp;
#end
and voila, it does exactly what you'd expect. I dug up this gem from one of Mike Ash's old blog posts.
Private API tricks like this are great for research or in-house code. Just remember to excise it from your appstore-bound builds.
Given that you already have the IMP, you simply need a way to do a very raw forward of the method call to said IMP. And given that you are willing to use an NSInvocation like solution, then you could also build a similar proxy class.
If I were faced with this, I would create a simple proxying class that contained the IMP to be called and the target object (you'll need to set the self parameter). Then, I would write a trampoline function in assembly that takes the first argument, assumes it is an instance of the proxying class, grabs the self, stuffs it into the register holding argument 0, grabs the IMP and *JMPs to it as a tail call.
With trampoline in hand, you would then add that trampoline as an IMP for any selector on the proxying class that you want forwarded to a particular IMP....
To achieve any kind of generic mechanism like this, the key is to avoid anything having to do with rewriting the stack frame. Avoid the C ABI. Avoid moving arguments about.
An untested idea:
Could you use object_setClass() to force the selection of the IMP that you want? That is…
- (void)forwardInvocation:(NSInvocation *)invocation {
id target = [invocation target];
Class targetClass = classWithTheImpIWant();
Class originalClass = objc_setClass(target, targetClass);
[invocation invoke];
objc_setClass(target, originalClass);
}
I think your best choice is to use libffi. Have you seen the port to iOS at https://github.com/landonf/libffi-ios? I haven't tried the port, but i have successfully invoked IMP with arbitrary arguments on the Mac.
Have a look at JSCocoa https://github.com/parmanoir/jscocoa it includes code to help you prepare a ffi_cif structure from a Method and it also contains a version of libffi that should compile on iOS. (Haven't tested either)
You should probably have a look at how we swizzle the implementation of a certain method on an instance of an object in https://github.com/tuenti/TMInstanceMethodSwizzler
Basically, you swizzle the method for all object of a class so when its called it look up in a dictionary whats is the implementation which has to be called for the target object, falling back to the original implementation if not found.
You can also use the private invokeWithImp: method, but this is discouraged if you intent to submit the app to the store.
you could add the IMP to the class using class_addMethod under a new selector and invoke that selector.
the temporary method can't be removed though.