Protocols and accessing another class's methods - iphone

So I'm fairly new to objective-c and am trying to wrap my head around protocols. I'll use an example to illustrate my question.
Suppose I have a "Calculate" class that performs various methods. I also have "Class1" and "Class2" that perform the same methods in "Calculate".
Now from my understanding I can use protocols to access methods from "Calculate" without the need for inheritance (Therefore saving the need to replicate the same code in Class1 and Class2).
My understanding is also that I have to implement the protocols in Class1 and Class2, therefore I'd have to type out those methods anyways. So whats the point of protocols?
I want to use the methods of "Calculate" without making it a superclass of Class1 and Class2. So I started exploring protocols, I've read the documentation but I still don't understand how this is being achieved. If some one can explain protocols in layman's it would be appreciated.

Inheritance would allow you to not have to duplicate code. Protocols (what other programming languages call interfaces) implement a Can-Do structure of OOP. Meaning when a class implements a protocol, that class is saying that it can do a certain set of methods. It is still up to that class to implement the method as they see fit.
Here is a developer reference from Apple:
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html

A protocol is a set of method declarations. It's main purpose is to allow flexible relationships between classes.
Let's say I want a variety of classes to send out logging messages but I don't want them responsible for knowing what happens to the messages after they're sent. I create a Logger protocol that is then implemented by a ConsoleWriter class and a DiskWriter class. The class wanting to send the message doesn't know or care which one it's talking to; it just talks to something it knows as id<Logger>.

I don't know with what types of languages you have experience. But an Object-C protocol is very much like an Interface in .NET. It's purpose is to define a contract (interface, footprint, etc.) so that the actual "Type" of the object is not necessary to be known, but just what it can do.
That being said you can define a protocol "MyProtocol.h" that has a few properties and methods. Then you can implement this protocol on a class. You will not need to add the members of the protocol in the header of the class, but simply need to write the concrete implementation in the implementation.
What this does is allow you to reference object by their defined interface and not their type. So you can use the id type instead of the actual class type.
Hope this helps.

Protocols are almost like a portable header file. They describe methods that can or should be implemented by any class that conforms to the protocol. This is different from inheritance where a subclass automatically implements the methods of its super class and those methods can optionally be overridden on a subclass by subclass basis.
I suspect that you have some OOP background so I won't go too much into subclassing other than to say a subclass is very often a specialized or more specific version of the super class. In other words: every subclass is a kind of its superclass, but every superclass is not necessarily a type of subclass.
Protocols in ObjC are often used in delegate patterns where ClassA needs to know that ClassB can perform some kind of action. Here's an example:
// ClassA.h
#import "ClassB.h"
#interface ClassA <ClassBProtocol>
// Some variables
#end
// ClassA.m
#implementation ClassA
- (id)init {
if ( (self = [super init]) ) {
ClassB *classB = [[ClassB alloc] init]; // Create an instance of ClassB
classB.delegate = self; // Set ourself as the delegate which means we want ClassB to tell us what to do
}
return self;
}
// Introduced by ClassBProtocol
- (void)doSomethingCoolWithString:(NSString *)string {
// Do something here, it's up to ClassA what to do
}
#end
// ClassB.h
#protocol ClassBProtocol <NSObject>
- (void)doSomethingCoolWithString:(NSString *)string;
#end
#interface ClassB
#property (nonatomic, weak) id <ClassBProtocol>delegate;
// Some variables
#end
//ClassB.m
#implementation ClassB
#synthesize delegate;
- (id)init {
if ( (self = [super init]) ) {
if (delegate && [delegate respondsToSelector:#selector(doSomethingCoolWithString:)]) {
[delegate doSomethingCoolWithString:#"A String"];
}
}
return self;
}
#end

Below Example for Simple Protocol & Property:
---> ViewController.h File
#import <UIKit/UIKit.h>
#import "MyVC.h"
#interface ViewController : UIViewController<MyVCProtocol>
{
IBOutlet UILabel *label;
IBOutlet UIButton *btnPush;
MyVC *vc;
}
-(IBAction)Buttonclicked;
#end
---> ViewController.m File
#import "ViewController.h"
#implementation ViewController
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(IBAction)Buttonclicked
{
vc = [[MyVC alloc]initWithNibName:#"MyVC" bundle:nil];
vc.delegate=self;
[self.navigationController pushViewController:vc animated:YES];
}
-(void)GetText:(NSString *)text
{
label.textAlignment=UITextAlignmentCenter;
label.text=text;
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#end
---> MyVC.h File
#import <UIKit/UIKit.h>
#protocol MyVCProtocol <NSObject>
-(void)GetText:(NSString *)text;
#end
#interface MyVC : UIViewController
{
IBOutlet UITextField *m_TextField;
IBOutlet UIButton *m_Button;
id <MyVCProtocol> delegate;
}
#property(nonatomic, retain)id <MyVCProtocol> delegate;
-(IBAction)ButtonClicked;
#end
---> MyVC.m File
#import "MyVC.h"
#implementation MyVC
#synthesize delegate;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(IBAction)ButtonClicked
{
[delegate GetText:m_TextField.text];
[self.navigationController popViewControllerAnimated:YES];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end

Related

Delegates in iOS

I am a newbie to iOS world, so please ignore the obvious.
I am pushing a viewController(HelpViewController) on top of another viewController(MainViewController). When a particular action happens in the HelpViewController, I would like to update a variable inside the MainViewController. I understand for this I need to use delegate.
Here is my delegate header...
#protocol ViewControllerDelegate <NSObject>
#required
- (void) switchToggled:(BOOL)status;
#end
// Protocol Definition ends here
#interface ViewDelegate : NSObject
{
// Delegate to respond back
id <ViewControllerDelegate> _delegate;
}
#property (nonatomic,strong) id delegate;
-(void)sendMessage:(BOOL)status; // Instance method
#end
and implementation...
#implementation ViewDelegate
#synthesize delegate;
-(id)init {
self = [super init];
return self;
}
-(void)sendMessage:(BOOL)status
{
[delegate switchToggled:status];
}
- (void)dealloc
{
[super dealloc];
}
#end
So Now If I want to implement Protocol ViewControllerDelegate I need to specify in MainViewController, which I do as follows --
MainViewController <ViewControllerDelegate>
and
#pragma mark - ViewControllerDelegate delegate
-(void)switchToggled:(BOOL)status{
NSLog(#"Switch Toggled(%d) Message passed to MainViewController",status);
}
My question is how do I specify Object, which delegate property needs to point to, so that it can come back to MainViewController's "switchToggled".
One way I do is by having property inside HelpViewController as follows -
MainViewController.m
HelpViewController *helpVC = [[HelpViewController alloc] init];
helpVC.mainView = self;
[self.navigationController pushViewController:helpVC animated:YES];
[helpVC release];
HelpViewController.h
#property (nonatomic) MainViewController *mainView;
HelpViewController.m
#synthesize mainView;
ViewDelegate *myDelegate = [[ViewDelegate alloc] init];
// assign delegate
myDelegate.delegate = mainView;
[myDelegate sendMessage];
[myDelegate release];
Is this correct way to implement or there is better way to achieve this or am I totally wrong.
Thanks
You should do:
// HelpViewController.h
#protocol HelpDelegate
- (void)switchToggled:(BOOL)status;
#end
// HelpViewController.m
#interface HelpViewController : UIViewController
#property (nonatomic, assign) id<HelpDelegate> delegate;
- (id)initWithDelegate:(id<HelpDelegate>)delegate
#end
#implementation HelpViewController
- (id)initWithDelegate:(id<HelpDelegate>)delegate
{
if (self = [super init])
{
self.delegate = delegate;
}
}
- (void)sendMessage:(BOOL)status
{
[self.delegate switchToggled:status];
}
// MainViewController.h
#import "HelpViewController.h"
#interface MainViewController.h : UIViewController <HelpDelegate>
// MainViewController.m
- (void)someMethod
{
HelpViewController* viewController;
viewController = [HelpViewController alloc] initWithDelegate:self];
...
}
#pragma mark - Help Delegate
- (void)switchToggled:(BOOL)status
{
...
}
Give the delegate a name that makes clear to which class it belongs.
You don't need the extra class/files for ViewDelegate/ViewControllerDelegate. Just define the delegate in header of class it belongs to: HelpViewController.n in this case.
Similar: Implement the delegate method switchToggled: in the real class MainViewController, and not in the extra/unnecessary class ViewDelegate.
The purpose of delegates is to avoid class dependencies. By including MainViewController in HelpViewController you create such a dependency. This is not necessary as I show, and is wrong design.
You were also creating a circular dependency, because MainViewController already needed HelpViewController in order to show it, and now they need each other the other way around for sending the event.
Alternatively you can make HelpViewController's delegate public, have an init without argument, and expect users to set it with helpViewController.delegate = self; or something. But this would only make sense when the delegate being set is optional (which don't seems the case here, so adding it to the init method is appropriate).
I tell you what I would have done:
1) the protocol definition is ok, but do NOT create the class ViewDelegate, so:
//ViewControllerDelegate.h
#protocol ViewControllerDelegate <NSObject>
#required
- (void) switchToggled:(BOOL)status;
#end
2) Your implementation of the delegate method in MainViewController is ok.
3) Now... the important point:
//interface
#interface HelpViewController : UIViewController //or whatever superclass..
{
id <ViewControllerDelegate> _delegate;
}
#property (nonatomic,strong) id<ViewControllerDelegate> delegate;
#end
//implementation
#implementation HelpViewController
- (void)someMethodWhichCallsTheDelegate
{
//do something
...
// call delegate
//if switchToggled: were optional then add the following
//if ([self.delegate respondToSelector:#selector(switchToggled:)]) {
[self.delegate switchToggled:status];
}
#end
4) Now you have to assign the delegate:
//MainViewController.m
HelpViewController *helpVC = [[HelpViewController alloc] init];
helpVC.delegate = self;
[self.navigationController pushViewController:helpVC animated:YES];
[helpVC release];
And that's it!
BTW: if this delegate is related only to HelpViewControllerthen add the protocol definition where you define the interface of the class, it is not necessary to create a separate header file. If instead the protocol is "global", then it can have some sense to declare it separately.

event delegation

I have two uiviewcontroller: MainViewController and SecondaryViewControlle. In MainViewController I do:
[self.view addSubView:SecondaryViewControlle.view];
The SecondaryViewController is a button by pressing the function to be performed by a MainViewController. How to do?
You'd start by defining a protocol in your SecondViewControlle.h file, something like:
#protocol SecondViewControlleDelegate
- (void) doSomething
#end
You would also need to add a "delegate" ivar to your SecondViewControlle .h file. It would be the delegate line:
#interface SecondViewControlle : UIViewController
...
...
...
#property (nonatomic, assign) id delegate; // all you need to do is add this line inside your interface declarations
...
...
...
#end
Then, when you create / instantiate your SecondaryViewControlle from your MainViewController, make certain to add the MainViewController as the delegate like so:
SecondaryViewControlle.delegate = self;
[self.view addSubView:SecondaryViewControlle.view];
Now the "delegate" of your SecondaryViewControlle view controller points back to your MainViewController.
And when the button is pressed, you can simply do something like:
- (IBAction) buttonIsPressed: (id) sender
{
[delegate doSomething];
}
Now, I need to give you some advice here.
1 ) DO NOT use the class names as object names. Instead of having an object named "SecondViewControlle", name it something different (and start it with a lower case, which is Objective-C convention), something like "moreDetailVC".
2) I've told you how to do this with a delegate pattern, but this may not be the most appropriate way to do whatever it is that you're trying to do. After all, the MainViewController object (which should be renamed mainVC to differentiate the object from the class) is not on screen or visible so maybe there's a better place to put the functionality?
Option A
It's quicker, and easier, but lacks the maintainability, since there is no contract stating that SecondaryViewController needs to bother calling anything, and self.parentViewController could be any UIViewController.
Option B
The delegate pattern; this is my preference, it's obvious what's happening, what's required, and there's a nice solid contract that states, if you want to initialise me, give me a delegate.
Option C
If SecondaryViewController has to notify multiple objects, it would be quick to use the NSNotificationCenter, but as with Option A, there's no contract, should you need to notify many objects, you would need to remember to listen for notifications on those objects - since this is not the question, I won't go into detail, it's just here for the information
Option A
Within MainViewController.m, do something like so:
SecondaryViewController *viewcontroller = [[SecondaryViewController alloc] initWithNibName:#"SecondaryView" bundle:nil];
[self addChildViewController:viewcontroller];
//set viewcontroller.view frame
[self.view addSubview:viewcontroller.view];
[viewcontroller didMoveToParentViewController:self];
Inside MainViewController.h
-(void) performButtonClickAction;
Inside MainViewController.m:
-(void) performButtonClickAction {
//Do something constructive
}
and then inside the SecondaryViewController.m:
-(IBAction) buttonPressed:(id) sender {
[self.parentViewController performButtonClickAction];
}
Option B
Inside SecondaryViewController.h
#protocol SecondaryViewControllerDelegate <NSObject>
-(void) eventAFromViewController:(UIViewController *) viewController;
-(void) eventBFromViewController:(UIViewController *) viewController;
#end
#interface SecondaryViewController : UIViewController {
id<SecondaryViewControllerDelegate> delegate;
}
#property (assign, nonatomic) id<SecondaryViewControllerDelegate> delegate;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil delegate:(id<SecondaryViewControllerDelegate>) theDelegate;
#end
Inside SecondaryViewController.m
#synthesize delegate = _delegate;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil delegate:(id<SecondaryViewControllerDelegate>) theDelegate
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.delegate = theDelegate;
}
return self;
}
-(IBAction) buttonPressed:(id) sender {
if( self.delegate != nil ) {
[_delegate eventAFromViewController:self];
}
else {
//No delegate
}
}

Getting the delegate to work between two view controllers

I am a newbie to iPhone development and have some basic questions to ask about protocols and delegates. I have two view controllers: view controller and viewcontroller2nd. I have UITextField in one of them and would like to type something (like a name) in it and in the viewcontroller2nd, I have a UILabel and i would like it to appear Hello, name when the UITextField is changed.
I am following this video: http://www.youtube.com/watch?v=odk-rr_mzUo to get the basic delegate to work in a single view controller.
I am using protocols to implement this:
SampleDelegate.h
#import <Foundation/Foundation.h>
#protocol ProcessDelegate <UITextFieldDelegate>
#optional
- (BOOL)textFieldShouldReturn:(UITextField *)textField;
#end
#interface SampleDelegate : NSObject
{
id <ProcessDelegate> delegate;
}
#property (retain) id delegate;
#end
SampleDelegate.m
#import "SampleDelegate.h"
#implementation SampleDelegate
#synthesize delegate;
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
lbl.text = [NSString stringWithFormat:#"Hello, %#",txtField.text];
[txtField resignFirstResponder];
}
#end
ViewController.h
#import <UIKit/UIKit.h>
#import "SampleDelegate.h"
#interface ViewController : UIViewController <ProcessDelegate>
{
IBOutlet UITextField *txtField;
}
#end
Viewcontroller.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
ViewController2nd.h
#import <UIKit/UIKit.h>
#interface ViewController2nd : UIViewController <ProcessDelegate> {
IBOutlet UILabel *lbl;
}
#end
and ViewController2nd.m is standard code from Xcode.
My question is how do i link my delegate function to my viewcontroller and viewcontroller2nd to get it working?
Pardon me if the question is stupid.. Need some guidance. Do point me any other mistakes that i am doing as well.. Thanks..
Your delegation is a bit... Off.
Firstly: Don't override UIKit delegate methods through protocol inheritance. It's pointless. Why not just make your class conform to the specified delegate in the first place?
#protocol ProcessDelegate //No more protocol inheritance!
//...
#end
Secondly: When an object has defined a protocol, a valid instance of that object must be in use by its delegate (or at least passed to it). So, anything that wants to be the delegate of SampleDelegate (really a bad name for a class, by the way) would initialize a valid SampleDelegate object, and call -setDelegate: as though it were any other property.
//#import "SampleDelegate"
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//make this a property, so it isn't crushed when the function exits.
SampleDelegate *myDelegateObject = [[SampleDelegate alloc]init];
[myDelegateObject setDelegate:self]; //conform to the delegate
}
Thirdly: You don't actually define any delegate methods! What's the point of delegation if there's nothing to delegate!l
#protocol ProcessDelegate
-(void)someMethod;
#end
Fourth, and most important: Never, ever, ever, ever use the retain, or strong storage specifiers with a delegate! Delegate objects are supposed to be weak or assign to prevent nasty retain cycles.
#property (assign, nomatomic) id delegate;

MKMapViewDelegate derived class and delegate assignment

This is probably more of an objective-c question over iOS but I've seen some example code similar to the following that I'd like to better understand.
#interface MyMapView : MKMapView <MKMapViewDelegate> {
// ivars specific to derived class
}
#property(nonatomic,assign) id<MKMapViewDelegate> delegate;
#end
#implementation MyMapView
- (id) initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
// initialize the ivars specific to this class
// Q1: Why invoke super on this delegate that's also a property of this class?
super.delegate = self;
zoomLevel = self.visibleMapRect.size.width * self.visibleMapRect.size.height;
}
return self;
}
#pragma mark - MKMapViewDelegate methods
// Q2: Why intercept these callbacks, only to invoke the delegate?
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
if( [delegate respondsToSelector:#selector(mapView:regionWillChangeAnimated:)] )
{
[delegate mapView:mapView regionWillChangeAnimated:animated];
}
}
#end
My two questions are:
1. Why would one invoke the super.delegate and also only declare the 'delegate' as a property?
2. Why intercept all of the delegate calls only to forward them back to the delegate?
I appreciate any insights.
Apple's documentation explicitly states that you should avoid subclass MKMapView:
http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MKMapView_Class/MKMapView/MKMapView.html#//apple_ref/doc/uid/TP40008205
Although you should not subclass the MKMapView class itself, you can
get information about the map view’s behavior by providing a delegate
object.
So i guess this delegate "forward" pattern is used to not break things.
I use a little different approach to subclass MKMapView. To minimize breakage i use two classes. One that subclass MKMapView and just override the init/dealloc method and assign/release the delegate property to a instance of the other class. The other class is a subclass of NSObject that implements the MKMapViewDelegate protocol and will be the one that does the real work.
MyMapView.h
#interface MyMapView : MKMapView
#end
MyMapView.m
// private map delegate class
#interface MapDelegate : NSObject <MKMapViewDelegate>
// instance is not alive longer then MKMapView so use assign to also solve
// problem with circular retain
#property(nonatomic, assign) MKMapView *mapView;
#end
#implementation MapDelegate
#synthesize mapView;
- (id)initWithMapView:(ReportsMapView *)aMapView {
self = [super init];
if (self == nil) {
return nil;
}
self.mapView = aMapView;
return self;
}
// MKMapViewDelegate methods and other stuff goes here
#end
#implementation MyMapView
- (id)init {
self = [super init];
if (self == nil) {
return nil;
}
// delegate is a assign property
self.delegate = [[MapDelegate alloc] initWithMapView:self];
return self;
}
- (void)dealloc {
((MapDelegate *)self.delegate).mapView = nil;
[self.delegate release];
self.delegate = nil;
[super dealloc];
}
#end
The mapView property for MapDelegate class is not strictly needed but is probably useful if want to do things to the map view that that is not a result of some MKMapViewDelegate method call, timers etc.
Why would one invoke the super.delegate and also only declare the 'delegate' as a property?
Ans. As you are making a custom mapview it is important to call the delegates too.We are invoking the super class delegate to send control from the custom Mapview.
Why intercept all of the delegate calls only to forward them back to the delegate?
Ans.At that line of code we are sending back the control to that delegate method declared in super class to do some useful thing.
Hope it will solve the query.

how to extend a protocol for a delegate in objective C, then subclass an object to require a conforming delegate

I want to subclass UITextView, and send a new message to the delegate. So, I want to extend the delegate protocol. What's the correct way to do this?
I started out with this:
interface:
#import <Foundation/Foundation.h>
#class MySubClass;
#protocol MySubClassDelegate <UITextViewDelegate>
- (void) MySubClassMessage: (MySubClass *) subclass;
#end
#interface MySubClass : UITextView {
}
#end
implementation:
#import "MySubClass.h"
#implementation MySubClass
- (void) SomeMethod; {
if ([self.delegate respondsToSelector: #selector (MySubClassMessage:)]) {
[self.delegate MySubClassMessage: self];
}
}
#end
however with that I get the warning: '-MySubClassMessage:' not found in protocol(s).
I had one way working where I created my own ivar to store the delegate, then also stored the delegate using [super setDelegate] but that seemed wrong. perhaps it's not.
I know I can just pass id's around and get by, but My goal is to make sure that the compiler checks that any delegate supplied to MySubClass conforms to MySubClassDelegate protocol.
To further clairfy:
#interface MySubClassTester : NSObject {
}
#implementation MySubClassTester
- (void) one {
MySubClass *subclass = [[MySubClass alloc] init];
subclass.delegate = self;
}
#end
will produce the warning: class 'MySubClassTester' does not implement the 'UITextViewDelegate' protocol
I want it to produce the warning about not implementing 'MySubClassDelegate' protocol instead.
The UITextView defines its delegate as
#property(nonatomic, assign) id<UITextViewDelegate> delegate
meaning it conforms to UITextViewDelegate, and that's what compiler checks. If you want to use the new protocol, you need to redefine delegate to conform to your protocol:
#interface MySubClass : UITextView {
}
#property(nonatomic, assign) id<MySubClassDelegate> delegate
#end
The compiler shouldn't give any more warnings.
[Update by fess]
... With this the compiler will warn that the accessors need to be implemented... [I implemented this:]
-(void) setDelegate:(id<MySubClassDelegate>) delegate {
[super setDelegate: delegate];
}
- (id) delegate {
return [super delegate];
}
"
[My update]
I believe it should work if you only make a #dynamic declaration instead of reimplementing the method, as the implementation is already there:
#dynamic delegate;
For anyone still interested, this can be done quite simply like this (for sake of the example, I subclass UIScrollView):
#protocol MySubclassProtocol <UIScrollViewDelegate>
#required
-(void)myProtocolMethod;
#end
#interface MySubClass : UIScrollView
#property (nonatomic, weak) id <MySubclassProtocol> delegate;
The most important detail here is the part between the <> after your protocol's name which, put in a simple manner, signals you're extending that protocol.
In your implementation, all you need to do then is:
#synthesize delegate;
And you're done.
You need to extend the super protocol:
#protocol MYClassProtocol <SuperClassProtocol>
-(void)foo;
#end
after that DON'T (!!!) create the #property for the delegate otherwise you override the original delegate object, but simply override the method:
- (id<MYClassProtocol>)delegate
{
return (id<MYClassProtocol>)[super delegate];
}
now you can use the delegate in the classic way:
[self.delegate foo];
[self.delegate someSuperClassDelegateMethod];
Given that MySubClassMessage: is optional, you should be able to simple do a simple:
- (void) SomeMethod {
SEL delegateSelector = #selector(MySubClassMessage:);
if ([self.delegate respondsToSelector:delegateSelector]) {
[self.delegate performSelector:delegateSelector withObject:self];
}
}
The complier should still check that the implementing class conforms to your protocol (or at least claim to in the header) and you won't get the error you described.