Reputation: 9182
How can I prevent a method from getting overridden in a subclass, missing a call to its superclass' implementation within?.
I know calling [super methodName];
will solve my problem sometimes.
But if somebody else was to use my parent class and overrode my method, accidentally missing to call super, what can I do?
Some more explanations:
I create a viewcontroller VC1 which has a method -(void)indexDidChange:(int)index { }
. I write some actions there which I need to perform every time. and I subclass this viewcontroller named as SVC1 in it I need -(void)indexDidChange:(int)index { }
for doing some other actions but at the same time the VC1 -(void)indexDidChange:(int)index { }
action also need to perform. So I need to call like,
-(void)indexDidChange:(int)index {
[super indexDidChange:index];
}
So I decide to change VC1 function like,
-(void)indexDidChange:(int)index {
[self currentIndexDidChange:(int)index];
}
-(void)currentIndexDidChange:(int)index { }
And I need -(void)currentIndexDidChange:(int)index { } to override and prevent -(void)indexDidChange:(int)index { } from overriding.
Is it possible?
Upvotes: 3
Views: 2349
Reputation: 29562
Edit: After OP rephrased the question it is clear that OP is actually NOT looking for final methods, despite the questions initial phrasing, which implied just this.
According to your rephrased question you are not looking for protecting a method from being overridden at all, but rather worried about one of your subclasses overriding a method and accidently missing to include a call to super in its new implementation.
This however is a fairly common and widespread issue and something you're dealing with on a daily basis, without paying much attention to it.
Every Objective-C programmer is familiar with the following method, right?
- (void)dealloc {
[iVar release], iVar = nil;
[super dealloc]; //skipping this call to super is fatal!
}
And we al know that skipping the [super dealloc];
makes things get uncomfortable. (afaik the clang compiler issues a warning if dealloc lacks the call to super, …pretty handy.)
Despite the fact that a bad overriding of this method can have fatal consequences Apple did not choose to put any kind of security system in place here.
Instead Apple did this (as done with any other method requiring calls to super):
Keep in mind that - (void)dealloc
is by no means an exception. There are dozens and dozens of methods of this type in Cocoa. (Take just about any derivative of - (id)init
, most of the KVO observing methods, etc. just to name a few.)
So what you should do is:
super
, telling the reader/dev to look up documentation, when in doubt of the rules. (optional)What you are asking for is the equivalent of a final function, as known from Java or C++. Unlike Java or C++, however there are no final methods in Objective-C.
Depending on your situation there are solutions that might bring your at least near to what you're aiming for. All you'll get though is slightly better separation. You won't get any significant security from them. In Objective-C you cannot even be sure about the origin of your methods. Method swizzling allows you to exchange methods at will. With code injection you an even inject code into processes at runtime. All this is by design of Objective-C. Objective-C allows you to saw off the branch you're sitting on. Thus it demands you to act like a grown-up. As such there are no private methods either. If a method is proclaim private you as a dev are expected to behave accordingly.
Now to possible "solutions":
If only your super class if supposed to call the given (final) method anyway:
If subclasses however are expected to call the given (final) method:
NSArray
, NSDictionary
, NSSet
classes do this)However you might notice that with Objective-C lack of protection one usually can only choose between the two: openness, protectedness, not intermix them.
Upvotes: 8
Reputation: 3400
If you don't declare your function in the ".h file" then its not listed, I think.
Upvotes: 0
Reputation: 54059
You can use categories in the implementation, so your methods aren't exposed in your header file.
MyClass.m
@interface MyClass( Private )
- ( void )myMethod;
@end
@implementation MyClass( Private )
- ( void )myMethod
{}
@end
@implementation MyClass
/* ... */
@end
Upvotes: 4