MPPopoverControllerDelegate.h file
#import <Foundation/Foundation.h>
#class MPPopoverController;
#protocol MPPopoverControllerDelegate <NSObject>
#optional
- (void)popoverControllerDidDismissPopover:(MPPopoverController *)popoverController;
#end
MPPopoverController.h file
#import <UIKit/UIKit.h>
#protocol MPPopoverControllerDelegate;
#interface MPPopoverController : UIViewController <MPPopoverControllerDelegate>
#property (nonatomic, assign) id<MPPopoverControllerDelegate> delegate;
#end
MPPopoverController.m file
#import "MPPopoverController.h"
#import "MPPopoverControllerDelegate.h"
#implementation MPPopoverController
#end
#property (nonatomic, assign) id<MPPopoverControllerDelegate> delegate; : this line has warning
Cannot find protocol definition for 'MPPopoverControllerDelegate'
What is wrong? And how to fix this warning?
if replace '#protocol MPPopoverControllerDelegate'; with '#import "MPPopoverControllerDelegate.h', everything will be ok. But link - in Referring to Other Protocols you can see that apple says to use #protocol
Is there an absolute need for your protocol declaration to be in a different header file? Unless it's quite a large protocol definition (which yours isn't), I would suggest declaring it below your interface declaration.
MPPopoverController.h
#import <UIKit/UIKit.h>
#protocol MPPopoverControllerDelegate;
#interface MPPopoverController : UIViewController
#property (nonatomic, assign) id<MPPopoverControllerDelegate> delegate;
#end
#protocol MPPopoverControllerDelegate <NSObject>
#optional
- (void)popoverControllerDidDismissPopover:(MPPopoverController *)popoverController;
#end
Compiler read your .m file, and load .h files when necessary. So it loads MPPopoverController.h first and when it read it delegate protocol is still undeclared. You could easily fix this warning just by swapping include lines. To let compiler read delegate .h file first.
#import "MPPopoverControllerDelegate.h"
#import "MPPopoverController.h"
#implementation MPPopoverController
#end
Are you sure you're ever including MPPopoverControllerDelegate.h somewhere?
Import MPPopoverControllerDelegate.h in MPPopoverController.h and MPPopoverController.h should look like:
The code copy pasted from the question and edited was removed. The following code is copy pasted from xcode.
The MPPopoverControllerDelegate.h:
#class MPPopoverController;
#protocol MPPopoverControllerDelegate <NSObject>
#optional
- (void)popoverControllerDidDismissPopover:(MPPopoverController *)popoverController;
#end
The MPPopoverController.h
#protocol MPPopoverControllerDelegate;
#interface MPPopoverController : UIViewController{
id<MPPopoverControllerDelegate> delegate;
}
#property (nonatomic, assign) id<MPPopoverControllerDelegate> delegate;
#end
The MPPopoverController.m
#implementation MPPopoverController
#synthesize delegate;
//rest of view controller class.
The problem is that in your MPPopoverController interface you specify <MPPopoverControllerDelegate>. This means that the class implements this protocol! Is wrong because the class is the owner of the protocol. So your logic is wrong in some point.
Related
I have read question after question about people getting the same error as me, but I simply do not understand them, so before you go searching for duplicate questions, maybe someone can explain to me what I am doing wrong with this subclassing deal.
I have a subclass of UIImageView called swapView that I want to subclass to override the method -(void)count for special cases. I went to subclass this as I have any pre-existing UIKit class, but when I tried to build and run the project, I get this error:
Attempting to use the forward class 'swapView' as superclass of 'coinView'
I have tried putting both the #import statement of swapView and #class swapView in coinView.h and I've tried putting the import statement in coinView.m, but it refuses to build because of this continued error. If I move the import statement into the .m file, all references to the superclass's methods and properties, such as #property (nonatomic) int max; cause errors as well.
What am I doing wrong?
swapView.h
#import <UIKit/UIKit.h>
#import "ViewController.h"
#class ViewController;
#interface swapView : UIImageView
{
NSTimer* tmr;
}
#property (nonatomic) int current;
#property (nonatomic) int max;
#property (nonatomic, retain) UIImage* firstImage;
#property (nonatomic, retain) UIImage* secondImage;
#property (nonatomic) BOOL smallMax;
#property (nonatomic, retain) ViewController* pvc;
- (BOOL)testCollision:(CGPoint)point;
- (float)randomFloatBetween:(float)smallNumber bigNumber:(float)bigNumber;
#end
coinView.h
#import "swapView.h"
#class swapView;
#interface coinView : swapView
- (void)count;
- (void)move;
#end
For inheritance, the superclass MUST be inherited.
coinView.h
#import "swapView.h"
#interface coinView : swapView
- (void)count;
- (void)move;
#end
You're both forward declaring and importing ViewController.h in your swapView, which may cause compiler to complain.
swapView.h
#import <UIKit/UIKit.h>
#class ViewController
#interface swapView : UIImageView
.
.
.
#end
I have two classes where both of them have protocols to be implemented.
Can I implement one of the class's protocol in to the other and vice versa?
Does this cause any run time error?
Your problem is cyclic dependencies. Forward declaring won't really help either as you'll just get the compiler warning you that it can't see the definitions of the protocols. There are two options:
Option 1
Split the protocols out into their own header files:
ClassA.h:
#import <Foundation/Foundation.h>
#import "ClassBProtocol.h"
#interface ClassA : NSObject <ClassBProtocol>
#end
ClassB.h:
#import <Foundation/Foundation.h>
#import "ClassAProtocol.h"
#interface ClassB : NSObject <ClassAProtocol>
#end
ClassAProtocol.h:
#import <Foundation/Foundation.h>
#protocol ClassAProtocol <NSObject>
...
#end
ClassBProtocol.h:
#import <Foundation/Foundation.h>
#protocol ClassBProtocol <NSObject>
...
#end
Option 2
If you don't care about declaring externally that you implement the protocols, then you could use the class continuation category:
ClassA.h:
#import <Foundation/Foundation.h>
#interface ClassA : NSObject
#end
ClassA.m:
#import "ClassA.h"
#import "ClassB.h"
#implementation ClassA () <ClassBProtocol>
#end
#implementation ClassA
#end
ClassB.h:
#import <Foundation/Foundation.h>
#interface ClassB : NSObject
#end
ClassB.m:
#import "ClassB.h"
#import "ClassA.h"
#implementation ClassB () <ClassAProtocol>
#end
#implementation ClassB
#end
But, I dont suppose this is really necessary. Once you have a delegate implemented then you could send a message to the other class as it the same delegate object. I suppose a simple delegate relations as;
Class A
#protocol ClassAProtocol;
#interface ClassA:NSObject
#property(nonatomic, assign) id<ClassAProtocol> delegate;
#end
#protocol ClassAProtocol <NSObject>
-(void)classA:(ClassA*)classa didSomething:(id)object;
#end
#implementation ClassA
-(void)classAFinishedSomething{
[self.delegate classA:self didSomething:nil];
[(ClassB*)self.delegate doSomething];
}
#end
Class B
#interface ClassB : NSObject<ClassAProtocol>
-(void)doSomething;
#end
#implementation ClassB
-(void)doSomething{
}
-(void)classA:(ClassA*)classa didSomething:(id)object{
}
#end
This will not create a circular reference between the two objects and keep the code clean I suppose. This logic is valid if the delegate is always class B and it respondsToSelector:, the one being sent as a message to class B. But, the above sample posted by matt is mode rigid if you want to have isolate the log between the classes and communicate via standard mechanism.
I have this class where I have something like this on .h
#interface myClass : UIImageView <UIGestureRecognizerDelegate>{
#public id referenceOne;
#public id referenceTwo;
}
#property (nonatomic,retain) id referenceOne;
#property (nonatomic,retain) id referenceTwo;
on .m I have
#synthesize referenceOne, referenceTwo;
This class has no delegate protocol.
I have other classes that are based on this one. For one of these classes I have defined a delegate protocol and have my implementation file like this:
#protocol MyBasedClassDelegate <NSObject>
#optional
- (void) doStuff;
#end
#interface MyBasedClass : myClass {
id<MyBasedClassDelegate> _delegate;
}
#property(nonatomic,assign) id<MyBasedClassDelegate> delegate;
and on .m I have
#synthesize delegate;
as soon as I have defined this MyBasedClassDelegate the class stopped seeing the referenceOne and referenceTwo ids inherited from myClass. Now Xcode says these are not declared. If I disable the protocol, it sees the references again.
Why is that and how do I solve that?
thanks.
You have an error here:
#interface MyBasedClass : myClass {
id<MyBasedClassDelegate> _delegate;
}
rename to
#interface MyBasedClass : myClass {
id<MyBasedClassDelegate> delegate;
}
OR
do #synthesize delegate = _delegate; instead
EDIT:
Works well for me
myClass.h
#import <Foundation/Foundation.h>
#interface myClass : UIImageView <UIGestureRecognizerDelegate> {
id referenceOne;
id referenceTwo;
}
#property (nonatomic,retain) id referenceOne;
#property (nonatomic,retain) id referenceTwo;
#end
myClass.m
#import "myClass.h"
#implementation myClass
#synthesize referenceOne, referenceTwo;
#end
MyBasedClass.h
#import <Foundation/Foundation.h>
#import "myClass.h"
#protocol MyBasedClassDelegate <NSObject>
#optional
- (void) doStuff;
#end
#interface MyBasedClass : myClass {
id<MyBasedClassDelegate> delegate;
}
#property(nonatomic,assign) id<MyBasedClassDelegate> delegate;
#end
MyBasedClass.m
#import "MyBasedClass.h"
#implementation MyBasedClass
#synthesize delegate;
-(void) dosmth {
referenceOne = nil;
}
#end
If you change the variable name "_delegate" to "delegate", I think it might work. (Alternatively, comment out the synthesize line and it should also work).
I ran into a similar thing earlier today -- if you synthesize properties for instance variables that do not exist, the compiler doesn't complain but for some reason you can no longer see the superclass's variables.
For me it was finding http://www.iphonedevsdk.com/forum/iphone-sdk-development/53261-unable-access-superclass-member-variables-subclass-implementation.html that helped.
Ok, This has been explained a few times (I got most of the way there using this post on SO), but I am missing something. I am able to compile cleanly, and able to set the delegate as well as call methods from the delegate, but I'm getting a warning on build:
No definition of protocol 'DetailViewControllerDelegate' is found
I have a DetailViewController and a RootViewController only. I am calling a method in RootViewController from DetailViewController. I have the delegate set up as so:
In RootViewController.h:
#import "DetailViewController.h"
#interface RootViewController : UITableViewController <NSFetchedResultsControllerDelegate, DetailViewControllerDelegate> //Error shows up here
{
//Some Stuff Here
}
//Some other stuff here
#end
In RootViewController.m I define the delegate when I create the view using detailViewController.delegate = self
In DetailViewController.h:
#protocol DetailViewControllerDelegate;
#import "RootViewController.h"
#interface DetailViewController : UITableViewController <UITextFieldDelegate>
{
id <DetailViewControllerDelegate> delegate;
}
#property (nonatomic, assign) id <DetailViewControllerDelegate> delegate;
#end
#protocol DetailViewControllerDelegate
//some methods that reside in RootViewController.m
#end
I feel weird about declaring the protocol above the import in DetailViewController.h, but if I don't it doesn't build. Like I said, the methods are called fine, and there are no other errors going on. What am I missing here?
pheelicks is pretty much there but it looks like some of your protocol methods also use the DetailViewController class, I imagine it looks something like this :
#protocol DetailViewControllerDelegate <NSObject>
- (void) controller:(DetailViewController *)controller hasSomething:(id)thing;
#end
#class DetailViewController : UITableViewController <UITextFieldDelegate> {
id <DetailViewControllerDelegate> delegate;
}
#property (nonatomic, assign) id <DetailViewControllerDelegate> delegate;
#end
and you haven't defined DetailViewController yet so you will get an error in the protocol definition.
You can fix this in two ways :
a) Declare (but don't define yet) the class before the protocol
#class DetailViewController;
#protocol DetailViewControllerDelegate <NSObject>
- (void) controller:(DetailViewController *)controller hasSomething:(id)thing;
#end
b) Just use UITableViewController instead of DetailViewController in your protocol methods.
#protocol DetailViewControllerDelegate <NSObject>
- (void) controller:(UITableViewController *)controller hasSomething:(id)thing;
#end
Personally, I choose solution (a) but it really depends on what you're trying to do.
Hope that helps.
Try:
In DetailViewController.h:
#import "RootViewController.h"
#protocol DetailViewControllerDelegate <NSObject>
//some methods that reside in RootViewController.m
#end
#interface DetailViewController : UITableViewController <UITextFieldDelegate>
{
id <DetailViewControllerDelegate> delegate;
}
#property (nonatomic, assign) id <DetailViewControllerDelegate> delegate;
#end
Here is another way that you could tackle this, similar to the solution proposed by deanWombourne.
#protocol DetailViewControllerDelegate;
#interface DetailViewController : UITableViewController <UITextFieldDelegate> {
id <DetailViewControllerDelegate> delegate;
}
#property (nonatomic, assign) id <DetailViewControllerDelegate> delegate;
#end
#protocol DetailViewControllerDelegate <NSObject>
- (void) controller:(DetailViewController *)controller hasSomething:(id)thing;
#end
I am trying to create a delegate protocol for a custom UIView. Here is my first attempt:
#protocol FunViewDelegate
#optional
- (void) funViewDidInitialize:(FunView *)funView;
#end
#interface FunView : UIView {
#private
}
#property(nonatomic, assign) id<FunViewDelegate> delegate;
#end
This doesn't work because the FunView interface has not been declared at the time of the FunViewDelegate declaration. I have tried adding a prototype ala C++ before the #protocol:
#interface FunView;
But this just drives the compiler nuts. How am I supposed to do this?
Forward class syntax is #class Foo;, not #interface Foo;.
It would seem that you can forward declare protocols:
#protocol FunViewDelegate;
#interface FunView : UIView {
#private
id<FunViewDelegate> delegate;
}
#property(nonatomic, assign) id<FunViewDelegate> delegate;
#end
#protocol FunViewDelegate
#optional
- (void) funViewDidInitialize:(FunView *)funView;
#end