I'll caveat here: the particular case you're describing probably shouldn't be done this way. It's almost certainly over-clever and should probably be separated into viewDidLoad
and viewWillAppear
rather than two versions of viewWillAppear
. That said, the problem does come up.
My preferred solution to this is to keep a SEL
that points to what I want to do. For instance, I use this kind of technique for a "next action" after a complicated asynchronous activity:
if (self.nextActionSelector != NULL)
{
[self performSelector:self.nextActionSelector];
}
So for this, you could use a viewWillAppearSelector
that would be changed over time, and viewWillAppear
would just call whatever it points to.
Ben's recommendation of Method Swizzling is useful in some cases, but more often when you're trying to modify the behavior of some existing object rather than yourself. It can really make debugging fun.... OK, not actually fun. Painful. Very painful.
Beyond that, I'd look at -forwardInvocation:
, which can be used to respond to messages you don't directly implement. You can then rewrite the invocation to call the method you really want. This isn't really the way it's meant to be used, though. It's for forwarding calls to other objects transparently. But at least debugging it isn't that difficult since the debugger will go where you expect it to.
Generally in this case, rather than a boolean, I look for the evidence that I've been run before. Checking if view
is set already, or some other value that is initialized the first time so I don't need a special variable and so I'm resilient to things that clear my state (like iPhone's practice of dumping things when memory is tight). Where possible, I make these things self-initialize in their getters rather than having some external party have special first-time logic. Keeping the logic here simple makes maintenance much easier, and hey, NSInvocation
is crazy-slow (ok, you wouldn't notice it except in a tight loop, but it is about 500x slower than a method call in my tests. That said, I'm not suggesting making this decision on performance, just maintainability).