I just started learning this, so sorry if this has some obvious solution I still can’t grasp.
I have these two classes:
@implementation Person
-(void)saySomething:(NSString*) something {
NSLog(@"%@",something);
}
-(void)yellSomething:(NSString*) something {
[self saySomething:[something uppercaseString]];
}
@end
and
@implementation ShoutingPerson : Person
-(void)saySomething:(NSString*)something {
[super yellSomething:something];
}
@end
This is causing a circular reference call because saySomething is always being called on the descendant class.
How can I make yellSomething invoke the saySomething method on Person class instead of the descendant class ?
As Jonathan says, you really should avoid this if at all possible. It’s just a bad design to need this functionality. If your base class is intended to be subclassed, its documentation should spell out which methods must be overridden and which others may be overridden. Anything else should not be overridden, to avoid problems like this.
That said, if you are in a very unusual situation where it is necessary (perhaps you’re stuck working with 3rd party code that you cannot refactor), it is possible. But it’s not pretty. You need to call objc_msgSendSuper or objc_msgSendSuper_stret manually, after constructing an instance of struct objc_super pointing to
selfandYourBaseClass.Note that if you’re coming from C++ the default behaviour there is the same – if you call
SomeFunction()from your base class and it’s a virtual method, the subclass’s override will be executed. You would have to prefix your call to spell out the class explicitly, e.g.MyBaseClass::SomeFunction(). There’s no direct equivalent for that in Objective-C – I’d say because it’s just such a bad idea generally.