Overriding Delegate Methods when subclassing in Cocoa - objective-c

Suppose I have a class Foo which declares a delegate protocol with 3 methods. I would like to subclass Foo into a class called Bar and completely override these methods.
Should I declare them in the subclass header again?
When I implement these 3 methods inside of Bar's delegate, do I have to take any precautions to make sure Foo's implementation will not be used?

Should I declare them in the subclass header again?
That won't be necessary, as your Bar.h will import Foo.h and therefore know it conforms that protocol.
When I implement these 3 methods inside of Bar's delegate, do I have
to take any precautions to make sure Foo's implementation will not be
used?
The only precaution you need to take is to not call [super delegateMethod]; on your implementations, and you're good to go.

Related

Is it OK to override UIViewController methods on a category on UITableViewController

I know you should not override methods in a category that are defined in the class the category is for. But what about overriding inherited methods. Is that OK?
Specifically, UITableViewController inherits methods like viewWillAppear:, viewWillDisappear, viewDidLoad: and so on, from UIViewController.
So, let's say in a category on UITableViewController, we override those methods inherited from UIViewController.
Is it OK?
As far as I can tell, this will only break if Apple in some future version of UIKit decides to override these methods in UITableViewController.
Are there other reasons not to do this?
EDIT:
So the part about overriding methods in categories in the documentation passed under my radar, so thanks for the answer.
I'll have to solve this with subclassing and possibly extensions.
Overriding methods in a category is discouraged. See Overriding methods using categories in Objective-C
In my opinion it doesn't matter if this means overriding an inherited or class-defined method. Why should it make a difference? Why not subclass?

why must i inherit NSobject instead of NSapplication to implement delegate method on GNUSTEP?

I've seen several Obj-C tutorials. The delegate classes all inherit from NSObject. For example, the applicationDidFinishLaunching delegate method, in some tutorials, it inherited from NSObject but NSApplication to implement it. The reason I don't think it should inherited from NSObject is that I didn't find any delegate protocol declaration in it, but I found that delegate protocol declaration in NSApplication. My Objective-C toy environment is GnuSep.
Here is some code:
#interface browserController : NSObject //here. inheriting from NSObject,but NSObject don'have any protocols declaration about applicationDidFinishLaunching.
{
NSBrowser *browser;
}
#end
#implementation browserController
- (void)menuAction:menuItem
{
..............................
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSWindow *win;
ActiveBrowserDelegate * abd;
WindowDelegate *wd;
NSRect wf = {{100, 100}, {600, 500}};
NSRect bf = {{10, 10}, {580, 350}};
.............................
}
It is called informal protocol (though GNUstep declared it anyway as GSAppDelegateProtocol for documentation purpose) NSApplication will simply check it at runtime if your delegate object will respond to the message, (using -respondsToSelector:) A delegate can be a view, a string, a proxy, anything as long as you make it responds to the selector. You don't need to make your delegate implement every method in such protocol since all verifications would be done at runtime. To make it looks cleaner you could just redeclare -applicationDidFinishLaunching: in #interface though you don't really need to, just make one in the #implementaiton is enough.
A delegate may inherit from anything appropriate. It is usually supposed to implement a certain protocol.
A protocol is a way of implementing a formal communication interface between two classes.
However, it is most unlikly that a delegate will inherit from its communication partner class.
With other words: Protocols are often used to overcome the unavailability of multiple inheritance. (Pretty much like interfaces in Java)
Example: A UIViewController subclass' instance controls a view that contains a UITableView. Rather than subclassing the UITableView for the implementation of its look or data, there are two delegates assigned to the table view object. One delegate serves as provider for custom layout (provides items such as the header view) and another (?) delegate provides the data that is being displayed.
Now, this delegate could be any object, inheriting from NSObject and implementing the two protocols. This object cold then be instanciated by the view controller and assigned to the table.
However, it is common practice that the view controller itself serves as delgate for the table(s) that it controls. That is a good pattern but strictly spoken not required. It could be any object.
Now the custom view contoller inherits from UITableViewController (which already implements the protocols and inherits from ViewController) and serves as delgate for the table view. The table view itself could be any subclass of UITableView. (Although this is a bad example here because subclassing UITableView is normally not advisable)
If the delegate does not need to inherit from any class and just implements the protocol, then it shold at least inherit from the cocoa base class NSObject. That ensures that it inherits all the usual capabilites and behaviour of any object. (init method, copy method, description method etc.) That may be required to work properly with other classes of the framework such as beeing used as an object within an NSArray, NSLog etc.

overriding undeclared methods in subclass

I have a class with some methods neither declared in .h file nor in any category, I want to override these methods in the subclass to change the behavior slightly. I am thinking of simply redefining those methods in subclass. Is it a good idea? would it even work?
Ideally the subclass needs to know what the methods are if it wants to override the method and still call super.
One way of doing this is by having a separate header file which both the super class and subclass implementations both import.
// MyClass_protected.h
- (void)someMethodThatYouWantSubclassesToBeAbleToOverride;
Then
// MyClass.m
#import "MyClass_protected.h"
// MySubClass.m
#import "MyClass_protected.h"
It'll 'work' in that the compiler allows it. The class that defines these methods probably assumes they do particular things when called, which your implementation needs to respect when overriding them to avoid introducing bugs in the use of the class's interface.
You can override private methods in a base class but the problem is that you can't call [super someMethod]. If you wish to completely replace the original method then this isn't an issue.
Otherwise you need to let the derived class know about the methods in the parent class.

In ObjC, how do I hide implementation a superclass's methods in a subclass?

In ObjC, how do I hide implementation a superclass's methods in a subclass?
I'm not sure if #private would do the trick, as it appears to only apply to ivars.
You're right, the #private directive is for instance variables, not methods. To hide a method's implementation, simply omit its declaration from the header file. To suppress warnings, you can use use a category or class extension to declare the method in the .m file.
There's no built-in language feature to prevent a subclass from seeing the method, though. Why would you want to do that?
There are no actually "private" methods in Obj-C; since any message can be sent to any object at runtime, there's no way to prevent someone from sending the message you care about.
That said, you can intercept that message in the subclass and not handle it. The simplest way to make a superclass's method inaccessible is to override it in the subclass and do nothing:
- (void)someMethodIDontWantToSupport
{
}
MARK as in subclass interface file.
- (void)someMethodIDontWantToSupport __unavailable;

without applicationDidFinishLaunching in Objective-C

I've many classes in my XCode project, and only the class from where the control comes from main.m will be having applicationDidFinishlaunching method. in my other classes will the methods in it knows how to go to its own method implementation, or do i need to write init method?
I'm not sure I understand what you are asking about, but I will try.. :-)
applicationDidFinishLaunching is part of the UIApplicationDelegate protocol. Typically, only one class will implement this protocol in one application.
In you other classes, you implement the init method if you need to do something when an instance of that class is created, like instantiating and initializing property values for that instance.