Overriding super class methods in Objective-C - objective-c

If subclass in objective-c wants to override a super class's method, does it have to match the return type too?

Yes, it must have the same selector.
update:
IIRC the arguments also needs to have the same types.
update:
It seems that all methods of the same selector needs to have equivalent types across all classes when linking dynamically, not so with static linking: linky

Yes, It be same,
But one thing to be noted is you need to pass the super-class of return types.
Eg:
-(UIScrollview)method:(id)argument;
you can return UIview as well. (simply saying super class of return types).

Related

objective-c override system method

I find a c++ system method causes crash in ios and I try to swizzle the method. However, I do not how to do that because it's a method of a c++ class. Anyone know whether can I do that?
Method swizzling is unique to objective-c (and even there one has to use it carefully), and is not applicable to c++.
I suppose that you don't have access to the source code of the c++ class.
Then the only way to "exchange" the implementation of a method at a specific c++-class is to derive a subclass, override the method, and then make sure that the subclass is used instead of the other class. It is still unlikely that you have a chance; the method being not virtual, the class to be replaced being used in non-polymorphic ways, the class to be replaced already having several subclasses, each of these points will prevent you from being successful.
Good luck though!

In Objective-C why is id used as return type for init methods?

I did some quick searching and couldn't find an answer for this.
I'm interested to know why in Objective-C, id is used as the return type for init methods.
My guess is that it's because if the class is overridden, you don't want to return an object of the superclass's type, but I'm interested to know if it's done for some other reason.
Yup. Your idea is right on the money. A subclass should still be able to use its superclass's initialization methods and return its own type instead of the super type and returning id allows it to do that.
The superclass type idea, while a good theory, doesn't really stand up: A NSString * is a NSObject *. There's no reason it can't be referred to as such.
Instead, I think it has more to do with function signatures. In a dynamic language like Objective-C, you can have no idea what class you're messaging. But the compiler must know what type is being returned. That and Objective-C's history of convention-based programming (rather than having strict rules) means that your subclass could return a NSRect (a struct) or NSInteger (a scalar) from init. It was kooky, but valid.
C++ has a similar problem, see Is the return type part of the function signature?.
So we needed a single type for all methods with a signature of -(id)init, and id was the only thing that made sense as it specified only that the return type was an instance. That's enough for the compiler to do the right thing. Now we have instancetype, which matches the class being messaged.
In the meantime Apple added a new way to declare the return type of init methods.
It is instancetype. Read more about it e.g. here
it's possible for init to actually return an instance of a different class, so id is used. can't say i've ever seen this happen in practice, but hey :)

Objective-C 2.0 and Categories

In objective-c if I have a class such as "Foo", and have a category for that class "Foo (bar)", but do not implement all the methods declared in the category, would I have to redeclare them in a subclass before I define them? My book says yes (not sure if this is a mistake, or has been changed), I don't see why this is the case.
Basically how do categories apply to subclasses?
Categories are orthogonal to class hierarchy. They apply to the class on where they are defined. At runtime, the category methods are added to the method table of the class. Subclasses can use them as if they were regular methods.
Be sure to (re-)read this chapter of Objective-C Programming Language about the subject.
If you want to override a category method in a subclass, you can to either by declaring it in the class interface, or by declaring a category for the subclass.
Hope it helps.
You don't need to redeclare the method, but you must be able to "see" the declaration if you are calling it internally. (i.e. #import 'Foo+bar.h' in your subclasses .m).
It is, however, not a good idea to declare a method but not implement it. Your application will crash if -[Foo someDeclaredButNotImplementdMethod] is called. At least provide an empty implementations (e.g. - (void)someDeclaredButNotImplementdMethod {}).

Implement a pure virtual method in 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."

Does the respondsToSelector method have to exist?

Does a method which I check for with respondsToSelector have to actually exist?
What if I only define it in the interface part and fail to implement it? I'm looking at a poor-man's virtual function in Objective-C.
First, yes the method actually has to exist for the check to succeed in the context you describe. respondsToSelector: will return NO if the method is not implemented.
More importantly, I think you mean a poor man's pure virtual function in Objective-C. All instance methods are "virtual" in Objective-C; since method lookup is done a run-time, the subclass' implementation will always be used, even from a pointer of the superclass type. In Objective-C, there is no such thing as a pure virtual base class. You can often achieve what you want by either using a #protocol to define an API or using a base class that provides an implementation that throws an NSNotImplementedException as its body. Subclasses would obviously have to override the implementation, making it effectively pure virtual.
Given that calling respondsToSelector: only makes sense when you don’t know whether a method exists, it’s not entirely clear what you mean.
If you mean, does some implementation of a method with the specified selector have to exist somewhere, the answer is no. Selectors merely represent names of methods. The #selector directive doesn’t reference any aspect of any method implementation.
respondsToSelector will return NO, since the selector isn't callable at run-time. The interface part only affects compilation.