views:

128

answers:

1

How would I find out where a method was called from? Like you see in a stack trace.

Basically, just to explain, I am observing a core data property and the method that gets called when the property changes calls another method (the IBAction) but in this IBAction it adds Core Data objects which triggers the KVO method which triggers the IBAction and so forth. That is why I was trying to figure out where the method was called from so I could stop this infinite loop.

+12  A: 

You can't without going to great lengths to duplicate the functionality of the debugger, dtrace, and/or the various other tools that do exactly this kind of thing. It is remarkably architecture dependent and rife with special cases and situations that flat out don't work.

You certainly would never want to do such a thing in production code. For debugging, there are enough tools that do this in enough contexts that there is no need to do so.

What are you trying to do?

Basically i'm using KVO and if the KVO method is triggered from another method which is an IBAction I don't what it to do what it would normally do otherwise it would go into a loop (related to my earlier question).

Down this path lies madness. It totally breaks encapsulation to have a method whose execution is impacted by a caller without their being some kind of explicit argument or implicit configuration indicating that the behavior should change.

If you are ending up in an infinite loop, then I would suggest revisiting your overall architecture.

In particular, when a KVO notification fires, it should almost never trigger a KVO notification of the same property either directly or indirectly. In the exceedingly rare case where this is unavoidable, you should make sure you do the KVO triggers by hand using -willChangeValueForKey: and -didChangeValueForKey: conditionally.

Basically, just to explain, I am observing a core data property and the method that gets called when the property changes calls another method (the IBAction) but in this IBAction it adds Core Data objects which triggers the KVO method which triggers the IBAction and so forth. That is why I was trying to figure out where the method was called from so I could stop this infinite loop

In other words, you have a model layer change that is then calling a method at the interface between view layer and control layer (the IBAction method) that then, not surprisingly, triggers another model level change which then goes off the rails....

Once your observer fires and you need to make a change in the model as a result, you should keep all of the change logic within the model layer. It is your model, after all, and it should have the smarts to apply changes appropriately.

What should never happen is that the control layer or view layer triggers changes to the model in response to the model changing. Changes to the model -- to the data -- from the control/view layer should only ever occur in response to user action or some external event (a timer, perchance).

bbum
Basically i'm using KVO and if the KVO method is triggered from another method which is an IBAction I don't what it to do what it would normally do otherwise it would go into a loop (related to my earlier question).
Joshua
Down that path lies madness as it entirely breaks encpasulation. YOu really don't want to go with design patterns where the *caller* transparently modifies *callee* behavior.
bbum
Basically, just to explain, I am observing a core data property and the method that gets called when the property changes calls another method (the IBAction) but in this IBAction it adds Core Data objects which triggers the KVO method which triggers the IBAction and so forth. That is why I was trying to figure out where the method was called from so I could stop this infinite loop.
Joshua
"Down that path lies madness" +10
nall
So what do you think i should do then if you think what I'm trying to do is madness?
Joshua
The design mistake is almost certainly in the comment that "when the property changes calls...**the IBAction**" Changes at the model layer should not be calling IBActions. IBActions are in response to user action, not model changes. This is a rewording of bbum's answer's final paragraph. If you are calling an IBAction by hand, you are almost certainly breaking KVC.
Rob Napier
It's calling an IBAction because that IBAction is also triggered by clicking a button in the interface.
Joshua
Would it fix the problem if I called a method (e.g `-(void) doSomething {…}`)?
Joshua
I have had to work with production code in a different programming language where someone who designed an application thought it would be a good idea to make the logic of subroutines work in different ways depending on who the caller was. The code was a nightmare to debug and maintain. As far as I know it was always unstable. As bbum says, for debuggers this is a handy thing to know but production code should not know it. It introduces coupling and complexity that should not exist.
JohnnySoftware