Implement a pure virtual method in Objective-C - objective-c

I want to go to there. Seriously though, how does one implement a pure virtual method in an "Apple" way? Do you use a Protocol with your base class and throw exceptions on those methods?

When you program in Objective-C you need to purge your mind of such things as virtual methods. You don't call methods on Objective-C objects, you send messages to them. Objects either respond to messages or they don't, but due to the dynamic binding, you can't tell this until run time.
Thus, you can declare a method on a base object and not not provide an implementation, no problem (except for the compiler warning), but you can't have the compiler flag up when you directly instantiate an object with such methods and it won't throw an error at runtime unless you actually send that message to the object.
The best way to create "virtual" base classes (in my opinion) is to declare the method and give it a stub implementation that throws a suitable exception.

In Objective-C, there is no pure virtual support as in C++.
A simulation would be that you declare a method in your interface but don't implement it in your .m file. Of course you'd get compiler warnings but IIRC you can turn those off. But you won't get warnings/errors if you don't overwrite them in the subclass, which you get in C++ (IIRC).
An alternative would be to implement them with just an NSAssert(NO, #"Subclasses need to overwrite this method"); body. Still, you'd only catch this at runtime, not compiletime.

Depending on what you're doing the delegate pattern may be more appropriate than a subclass, where the delegate is defined as id<YourDelegateProtocol>. The compiler will generate a warning if the required methods in the delegate protocol are not implemented.
Subclassing is generally avoided in Objective-C since objects cannot inherit from multiple superclasses but they can implement multiple protocols.

You should use the:
- (void)doesNotRecognizeSelector:(SEL)aSelector method.
As noted by Apple, here: https://developer.apple.com/library/mac/#documentation/cocoa/reference/Foundation/Classes/NSObject_Class/Reference/Reference.html

You have a few options, but you're on the right track.
ObjC doesn't support this directly, forcing subclasses to implement a protocol is the best way to check it at compilation.
'Secretly' implementing the method in the base class and asserting is what I do to confirm the subclasser has subclassed correctly at runtime. Some people have mixed feelings about assertions, or must leave them active, so that's not always a good solution.
You can also force subclasses use a specific class constructor and initialization sequence, then verify they have implemented everything required before returning an instance, in case compiler warnings don't cut it.
But ObjC is missing some lang features which allow clients to shoot themselves in the foot, or workaround what they wish so... you shouldn't get too stuck on enforcing it.
note: Exceptions are very uncommon (and a bit unsafe, too) in ObjC.

A virtual method is a method whose behavior can be overridden within an inheriting class by a function with the same signature (i.e same name with same number of params and type of params).
Example:-
#implementation BaseClass
-(void)viewDidLoad
{
[self virtualMethod:123];
}
-(void)virtualMethod:(int)param
{
//implement this method in subclass
}
#end
////////////////////////////////////////////////////
#interface ChildClass:BaseClass
#end
#implementation ChildClass
-(void)virtualMethod:(int)param
{
NSLog(#"There is no keyword "Virtual" in Objective C.");
}
#end
Output:-
"There is no keyword "Virtual" in Objective C."

Related

Can an ObjC class object conform to a protocol?

Is there a way to indicate to the compiler that a class object conforms to a protocol?
As I understand, by creating +(void)foo class methods, an instance of that class object will have those methods as instance methods. So, as long as I create +(void)foo methods for all required protocol methods, I can have a class object act as a delegate.
My problem of course is that in the class's header file, I only know how to indicate that instances of the class conform to the protocol (as is typically the case). So, the best I've figured out is to cast the class object like so:
something.delegate = (id<SomethingDelegate>)[self class]
Any ideas?
Related, but different:
ObjC: is there such a thing as a "class protocol"?
What you're doing now is correct as it will silence warnings which is your goal. You will be sending the class object messages defined in the protocol for instances which is a bit confusing, but the runtime doesn't care.
Think about it this way: you want to set a delegate to an object that responds to the messages defined in the protocol. Your class does this, and your class is also an object. Therefore, you should treat your class like an object that conforms to that protocol. Therefore, what you've written is completely correct (based on what you're trying to do).
One thing to note, though, is this class will not properly respond to conformsToProtocol:. This is generally okay for a delegate setup anyway (delegates don't usually check if the class conforms — they just check if it can respond to a selector).
As a side note, one thing you can do syntactically is:
Class<SomethingDelegate> variable = (Class<SomethingDelegate>)[self class];
The difference here is that the compiler will use the class methods from the protocol instead of instance messages. This is not what you want in your case, though.
There is no Objective-C syntax to indicate that a metaclass conforms to a protocol.
I think you can do it at runtime, by using class_addProtocol on the metaclass. But I haven't tried it.
I guess you could also write a +conformsToProtocol: method on your class, and lie about your conformance. This could have unexpected side-effects, since there's already a +conformsToProtocol: on NSObject (in addition to -conformsToProtocol:).
Neither of these will eliminate the need for a cast to shut the compiler up. Just use a singleton.

If Protocol method is marked #required, when not implemented, why does compiler issue a warning and not an error?

Assume that:
New Protocol is declared
Method in this protocol is marked #required
Class conforms to Protocol
Class does not implement the method mentioned in Protocol
At compile time, information about this method is known: i.e. that it is required and that this class and any other classes this class may may extend do not implement it.
Why in this case the compiler issues a warning and not an error?
Errors are only issued when the compiler cannot continue because something went terribly wrong.
When calling a method in Objective-C, the method lookup is done during runtime and not during compilation, which C++ does. In Objective-C a "message" is simply sent to the object, something like obj.executeCommand("Hey, can you execute function <name> for me?"). In C++ the object will be called directly, in a way like obj.<name>(). In the case of Objective-C the executeCommand() method is called, which exists. In C++'s case the function is called but it does not exist. These are methods that are linked on the compiler level, which means they both become memory addresses rather than names. executeCommand becomes 0x12345678 but it still uses the same message ("execute function <name>").
This is probably very confusing, but it's related to the way methods are implemented in different languages.
If you feel strongly about it, why not turn on -Werror?
I don't know the real answer but here is a use case that would go against it.
What if you implemented all of the protocol methods in a category???
Main interface declaration adopts the protocol however the protocol method implementation is in a category.
This is valid code but will show compile error if compiler was that strict !!
Objective-C is a dynamic language. The idea of what an implementation is, is different to a static language.
For the most part, it's in code that most of us implement inside the #implementation ... #end block.
But what if a method is not found? Then an object has a chance deal with it dynamically.
Imagine you have an interface for a sound effect player:
#protocol FX
- (void)playBeep;
- (void)playSiren;
- (void)playHonk;
#end
An implementation could have the files Beep.mp3, Siren.mp3, Honk.mp3 to play, but instead of implementing each of the methods, it could override -forwardInvocation: and parse the selector string, something like this pseudocode:
NSString *selName = NSStringFromSelector([invocation selector]);
if ([selName startsWith:#"play"]) {
NSString filename = fileNameFromSelector(selName);
[self playSoundFileNamed:filename];
}
This may seem contrived, but once you start using the dynamic features of the language, you will start finding more and more places where it makes sense. And by sense I mean, does this effort help in the long run?
In the above case, just add a -sound* method name to the interface, and drop in a appropriately named sound file. It just works.
Another example from personal experiments: how to deal with Core Data entities in a more natural way. I want to do this:
NSArray *people = [Person findAllWithNameLike:#"B%"];
instead of mucking about with predicates, fetch requests etc.
But I don't want to define every permutation of method in code.
How about if I wanted to build an XML builder? I would look at a dynamic approach. It has served Groovy Builders well (look at Groovy/Grails for examples).
One last example: I have a traits system where I can define behaviours in the form of groups of methods and have my objects assimilate this behaviour. So, while the compiler doesn't see an implementation for the interface my object conforms to, the implementation is injected into it from a trait class, using the Objective-C runtime. Why would I do this? I find many delegate methods are boiler plate, but at the same time, a single base class for each situation is not flexible enough. Instead of cut and paste from code samples, my 'samples' compile and run :) and any changes are reflected across all projects using the trait.
To really understand why all this is available to you, it is worth playing around with a Smalltalk environment (search Pharo or Squeak). This is where Objective-C has its roots.
And finally, to stop these warnings:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wprotocol"
#implementation ... #end
#pragma clang diagnostic pop
Because there are times when there are bogus "required" methods in a poorly designed protocol.
They should have been optional but someone insisted they are "required".
Thusly making this a run time issue rather than a compile bug is very very wise.

Introspect parameter of type: id to decide whether it is a class or a protocol

I have the following method:
-(void)SomeMethod:(id)classOrProtocol;
It will be called like this:
[self someMethod:#protocol(SomeProtocol)];
Or
[self someMethod:[SomeClass class]];
Within the method body I need to decide if |classOrProtocol| is:
Any Class(Class) OR Any Protocol(Protocol) OR Anything else
[[classOrProtocol class] isKindOfClass: [Protocol class]]
Results in a (build)error:
Receiver 'Protocol' is a forward class and corresponding #interface may not exist
So how can I tell a Protocol from a Class from anything else?
In Objective-C 2 (i.e. unless you use 32 bit runtime on OS X) Protocol is defined to be just a forward class, see /usr/include/objc/runtime.h. The real interface is nowhere declared. You can try to include /usr/inlcude/objc/Protocol.h by saying
#import <objc/Protocol.h>
but as is written there, no method is publicly supported for an instance of Protocol. The only accepted way to deal with Protocol instances is to use runtime functions, given in Objective-C Runtime Reference. It's not even publicly defined whether Protocol is a subclass of anything, and it's not even stated that it implements NSObject protocol. So you can't call any method on it.
Of course you can use the source code of the runtime to see what's going on. Protocol inherits from Object (which is a remnant from pre-OpenStep NeXTSTep), not from NSObject. So you can't use the familiar methods for NSObject-derived objects, including Class of NSObject-derived objects. See the opensourced implementations of Protocol.h and Protocol.m. As you see there, the class Protocol itself doesn't do anything, because every method just casts self to protocol_t and calls a function. In fact, as can be seen from the function _read_images and others in objc-runtime-new.mm, the isa pointer of a Protocol object is set by hand when the executable and libraries are loaded, and never used.
So, don't try to inspect whether an id is a Protocol or not.
If you really need to do this, you can use
id foo=...;
if(foo->isa==class_getClass("Protocol")){
...
}
But, seriously, don't do it.
This is not an issue 'caused by inability to determine whether it's class or protocol. The error is 'caused by missing interface of Protocol class. Make sure you import Protocol.m at the top of your implementation file where you're testing argument's type.
You can also try using NSClassFromString() function which will return Class object or nil. Do note though that if nil is returned it doesn't mean that argument is protocol. It just means that it could be undefined class too!
There is also method NSProtocolFromString which returns appropriate results - Protocol for protocol and nil for undefined protocol.

How can I prevent a method from being wrongly overridden

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?
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.
New (updated) answer to OP's question on method overriding safety:
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):
Add a note to the method's documentation:
After performing the class-specific
deallocation, the subclass method
should incorporate superclass versions
of dealloc through a message to
super
Expect you, the programmer, to be a grown-up and responsible for what you do. And for playing by the rules (as defined by the documentation).
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:
Write a good documentation for your
method. (better for your entire project, actually)
Add a big loud note to your method's documentation, explaining its rules.
Add a note to each of your subclasses' overridden method implementations, right above the line that's calling super, telling the reader/dev to look up documentation, when in doubt of the rules. (optional)
Code responsibly. Otherwise, you shouldn't be coding in first place. It's your customers who will suffer from it, eventually.
Old (pre-rephrasing) answer on archieving pseudo-final methods:
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:
Then Macmade's solution of making your method a pseudo-private method would work quite well. The downside of hiding method declarations though is, that calling your hidden method from subclasses will give you a compiler warning, basically preventing*(sic!)* you from calling it. (It will not prevent you from calling the method though. It will only avoid you from doing so, by throwing compiler warnings.)
If subclasses however are expected to call the given (final) method:
Use a delegation pattern and by this only make those methods public that are allowed to be overridden.
To prevent overriding at all you could use the class cluster & abstract factory patterns, which hides your implementation classes and thus preventing overriding entirely. (Apple's 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.
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
If you don't declare your function in the ".h file" then its not listed, I think.

Objective-C: Protocols

I'd like an instance variable object to adopt a protocol.
#interface GameScene : Scene <AVAudioPlayerDelegate> {
#private
Layer *content <CocosNodeOpacity>;
}
For example I'd like my Layer object to adopt the <CocosNodeOpacity> so that I can get the methods
-(GLubyte) opacity; //and
-(void) setOpacity: (GLubyte) opacity;
for free. The syntax shown above is invalid. Is it possible to achieve this without creating a new implementation file and creating a custom object? Thanks.
If these are all code you created, the best way to do this is probably to make the Layer class itself adopt the protocol, rather than the variable.
#interface Layer : NSObject <CocosNodeOpacity> { ... }
A key benefit to this approach is that the compiler will check whether you've implemented all required methods in the protocol at compile time, which is generally what you want. Adding the methods in same place as the rest of the standard class implementation is easier to understand (no hunting to find where the magical code came from) and less fragile than using categories (adding the same method via different categories can result in undefined behavior). As a general rule, I only use categories when I have to, such as adding methods to (closed-source) third-party code.
If you don't control the source of Layer, you may have to use this instead when you declare your ivar:
Layer<CocosNodeOpacity> *content;
Note that adopting a protocol allows you to statically type variables with a class type and get compile warnings if the methods aren't present. However, you don't get the methods "for free", since you still have to implement them. Still, judicious use of protocols and static typing can make your code more robust and "fail-fast" than using id as the type for everything. You are to be commended for not just taking the easy way out. :-)
For some details about protocols (including required and optional methods) see this SO answer.
A protocol in Objective-C is similar to an interface in Java. The protocol defines a set of functions and acts as a contract. It's like saying "I guarantee that whatever this object is, it has these methods."
You're pretty close on the syntax in your first code block. It would actually look something like this:
#interface GameScene : Scene <AVAudioPlayerDelegate> {
#private
Layer<CocosNodeOpacity> * content;
}
However, that doesn't save you from having to define the methods for opacity in your Layer class. Using the protocol, you've established that your class will have those functions, but you haven't actually provided them. You'll still need to write the code for them.
I think what you're looking for is an Objective-C category. A category provides a way to extend the functionality of any class by adding methods to it at runtime. They're possible because Objective-C is a completely dynamic language. If you aren't the author of the Layer class and can't easily add the opacity methods to it, a category is the way to go. In some cases, categories are extremely useful - you can add methods to built-in classes, like NSString and NSColor, without having the existing class source.
There's plenty of documentation for categories here on stack overflow. The apple docs are also very good. Here's an article to get you started:
http://macdevelopertips.com/objective-c/objective-c-categories.html