Trouble with error 'cannot find protocol declaration' - iphone

I got SO questions also same as this and I tried with solution but still its not working for mine so asked this again.
This is my VCWithProtocol.h
#protocol mydemoDelegate
#optional
-(void)demoDelegateMethodWithSuccess:(BOOL)yesOrNo;
#end
#interface VCWithProtocol : UIViewController
{
id<mydemoDelegate>mydelegate;
}
#property (nonatomic,assign)id<mydemoDelegate>mydelegate;
VCWithProtocol.m
`#synthesize mydelegate`
This is my class where I am trying to use my Delegate
#class VCWithProtocol;
#interface VCTOUseDelegate : UIViewController <mydemoDelegate> //here is where it shows error with cannot find protocol declaration
VCTOUseDelegate.m
VCWithProtocol *obj = [[VCWithProtocol alloc] init];
obj.mydelegate = self;
I tried with Importing VCWithProtocol but not working as well

Instead of #class VCWithProtocol; write #import VCWithProtocol.h
And some good practice Use capital letter for first character of any class name and protocol.
e.g. MyDemoDelegate and avoid retaining delegate use
#property (nonatomic,assign)id<mydemoDelegate>mydelegate;

Synthesize your mydelegate, and call
[self mydelegate];

You need to add #import "VCWithProtocol.h" to the top of your .m file.

#property (nonatomic,**weak**)id<mydemoDelegate>mydelegate;
delegate always needs weak link

Related

Why can't I use my View Controller as a property?

for some reason I get an error here
#import "OtherViewController.h"
#interface ViewController: UIViewController
#property (nonatomic, strong) OtherViewController *otherViewController;
this gives me an error saying 'unknown type name OtherViewController' why is this happening to me? Is this not the way to send messages to other view controllers. If so what is the way you are supposed to do this?
From what you have posted, there isn't anything wrong with what you have posted. That being said, you don't need to declare a property for the other VC. What you need to do is declare a public property on OtherViewController (like an NSString) and then you can access that property from the ViewController class. Something like (assuming you are using Storyboards):
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"MySegueID"]) {
OtherViewController *ovc = segue.destinationViewController;
ovc.myPublicNSStringProperty = #"Something";
}
}
Try to import the header in the .m file
#import "OtherViewController.h"
and in the header .h file add
#class OtherViewController;
I can't know for sure since there's not enough info given, but I've seen similar errors if you have circular imports. That is, if OtherViewController.h includes #import ViewController.
So, you could try using #class in one of them to avoid the circular references:
#class OtherViewController;
The, be sure to include in your ViewController.m:
#import "OtherViewController.h"

My #property is declared yet I still get may not respond to warning

I don't like warnings lying around and this one has been bothering me. Any ideas on what I am doing wrong? I have tons of properties using this same approach and none of them are giving me warnings. Why doesn't Xcode recognize this one?
While the app works as expected, Xcode gives me the following compile time warning:
'OnlinePeerBrowser' may not respond to '-setMyParent:'
My property declaration in OnlinePeerBrowser.h
#import "WelcomeViewController.h"
#interface OnlinePeerBrowser : UIViewController <UITableViewDelegate, UITableViewDataSource, NSNetServiceBrowserDelegate> {
WelcomeViewController *_myParent;
}
#property (nonatomic, assign) WelcomeViewController *myParent;
OnlinePeerBrowser.m has
#synthesize myParent=_myParent;
I am getting the warning on setMyParent in WelcomeViewController.m here...
#import "WelcomeViewController.h"
#import "OnlinePeerBrowser.h"
#implementation WelcomeViewController
- (void)peerPickerController:(GKPeerPickerController *)picker didSelectConnectionType:(GKPeerPickerConnectionType)type {
...
OnlinePeerBrowser *controller = [[OnlinePeerBrowser alloc]
initWithNibName:#"OnlinePeerBrowser" bundle:nil];
[controller setMyParent:self];
}
Also, what is weird is that I can not use the dot syntax here either.
controller.myParent = self;
gives me the following error:
/Users/vesselhead/Development/iPhone/DJBox/WelcomeViewController.m:254: error: request for member 'myParent' in something not a structure or union
I feel like I must be missing something very simple.
The code you've posted looks correct. That means that the compiler is pulling in another declaration of the OnlinePeerBrowser class from somewhere.
Check for circular imports.
Check if you have multiple copies of the OnlinePeerBrowser.h file.
Add the line #warning Testing to your OnlinePeerBrowser.h file. That warning should then appear in the log when you compile. If that warning doesn't appear then that file isn't being picked up by the compiler.
If it's a circular import then don't import "WelcomeViewController.h" in "OnlinePeerBrowser.h". Instead, use a forward declaration in OnlinePeerBrowser.h, e.g. #class WelcomeViewController , and import "WelcomeViewController.h" in OnlinePeerBrowser.m
Sometimes Circular Imports create an issue with the compiler.
Instead of using
#import "WelcomeViewController.h"
in OnlinePeerBrowser.h move that line to the OnlinePeerBrowser.m and add
#class WelcomeViewController
to the OnlinePeerBrowser.h
this will allow you to set the Class of myParent and _myParent to WelcomeViewController and not have the Circular Import.
Alternatively:
you may want to use a #protocol that the WeclomeViewController would have to adhere to. Then you would only have to import the Classes in one direction.
the implementation for a Protocol property would be as Follows
//#import "WelcomeViewController.h"
#protocol OnlinePeerBrowserParent <NSObject>
#required
- (NSString*) informationFromParent;
#end
#interface OnlinePeerBrowser : UIViewController <UITableViewDelegate, UITableViewDataSource, NSNetServiceBrowserDelegate> {
id<OnlinePeerBrowserParent> _myParent;
}
#property (nonatomic, assign) id<OnlinePeerBrowserParent> myParent;
notice the Protocol is on the OnlinePeerBrowser.h so you can import the OnlinePeerBrowser.h and get the Protocol by default.
finally you implement the Protocol in the WelcomeViewController as so
#implementation WelcomeViewController<OnlinePeerBrowserParent>
- (NSString*) informationFromParent
{
return #"My Parental Info";
}
...... etc

Expected specifier-list before "MainViewController / Method -x not found return type defaults to id

I have the following imports in my EquivalenceClassGroup
#import "MainViewController.h"
but then in my property in EquivalanceClassGroup.h:
#property (nonatomic, assign) MainViewController *myController;
I get this error: "Expected specifier-list before MainViewController when compiling
If I change the import to: #class MainViewController and comment out the import of MainViewController.h that error goes away but then then XCode can't find the methods in my MainViewController from EquivalenceClassGroup.m so from here:
-(id)initWithLetterNumbers: (int)numOfLettersInWord enteredLetter: (NSString *) str controller:(UIViewController *)controller {
myController = (MainViewController *) controller;
letterArray = [myController getLetterArray];
[myController getLetterArray];
I get: "Method -getLetterArray not found return type defaults to id" on that last line
I have this method defined in the MainViewController: -(NSArray*)getLetterArray;
and there are no errors in that interface file or the m file. In the equivalence class if I type in [myController then space, I cant seem to find any methods.
From the MainViewController class I do import the EquivalenceClassGroup and use the methods without any problems
You have to make sure that you import the MainViewController.h file in your .m file. All the #class does is tell the interface that there is such a class, but it doesn't tell it anything about the class. That is what #import essentially does. The #class in the .h file is just good programming practice to make sure that you are doubling importing or anything. Hope that helps!
I think you have to write #import "MainViewController.h" in EquivalanceClassGroup.h file and
#class MainViewController in MainViewController.h file.
#class MainViewController
in your EquivalenceClassGroup.h
#import "MainViewController.h"
in EquivalenceClassGroup.m
This is called "forward declaration" and is quite common.

Objective C Properties

I tried searching for this issue, but can't seem to find out what I'm doing wrong.
Here is my controller header:
#import <UIKit/UIKit.h>
#interface BabyLearnViewController : UIViewController {
UIButton *btnImage;
MediaManager* myMediaManager;
}
#property (nonatomic, retain) IBOutlet UIButton *btnImage;
#property (retain) MediaManager* myMediaManager;
- (IBAction)setNewImage;
#end
Here is my controller class:
#import "BabyLearnViewController.h"
#import "MediaManager.h";
#implementation BabyLearnViewController
#synthesize btnImage;
#synthesize myMediaManager;
I am getting the errors:
error: expected specifier-qualifier-list before 'MediaManager'
error: no declaration of property 'myMediaManager' found in the interface
Any ideas? Usually the 1st error comes up if you have a cylical reference. 'MediaManager' doesn't reference anything else. Any ideas?
Since you have no mentions of MediaManager class at the moment it is used in header file compiler can't figure out what "MediaManager" is and issues an error. Declare that class using forward declaration in your header file to let compiler know that MediaManager is actually a class:
#class MediaManager;
#interface BabyLearnViewController : UIViewController {
...
P.S. As an alternative you can import MediaManager.h in your header, but using forward declaration is preferred.
Place #import "MediaManager.h"
this in header file of BabyLearnViewController
try add #class MediaManager; before #interface

"Variable Undeclared" error when compiling to iOS Device, but not for Simulator

I have an custom UIVIewController that is the base class for other controllers and has an instance of a custom UIView variable that is accessed by inherited the classes.
BaseViewController.h
#interface BaseViewController : UIViewController {
UIView *_vwHeader;
}
#end
BaseViewController.m
#import "BaseViewController.h"
#implementation BaseViewController
-(void)loadView {
[super loadView];
_vwHeader = [[UIView alloc] init];
}
#end
CustomViewController.h
#import "BaseViewController.h"
#interface CustomViewController : BaseViewController
#end
CustomViewController.m
#import "CustomViewController.h"
#implementation CustomViewController
- (void)loadView
{
[super loadView];
[_vwHeader setHidden:NO];
}
#end
The problem is that when I am running it on the simulator everything works perfectly fine, but when I change to the device I have an error on the [_vwHeader setHidden:NO]; line which says: '_vwHeader' undeclared (first use in this function)
I already tried to do:
Comment this line of code, but then it gives me an error in another class using a variable from the base class the same way (It only returns one error at a time), so it seems that it is not an specific error in the view or the controller class as the error occurs in other clases with different types, such as UIView and NSObject types
Change target compiler configuration, such as: architectures (all of them), base sdk (all above 4.0) didn't change anything
What seem to solve the problem, but not completely
Creating a property for _vwHeader and accessing it by self._vwHeader or super._vwHeader seems to work, but having to create a property just to access a variable does not make me confortable, specially because I would have to do it for all variables in the same situation inside my project.
changed C/C++ compiler version: using Apple LLVM Compiler 2.1 makes the compilation error goes away, but gives a bunch of other problems with other libraries being used in the project. So, it is not a definitive solution, but might be a clue of what the problem is.
EDIT:
I tried to create another variable that is not a pointer, a BOOL instead of the UIView * and then used it in the inherited class: the problem also occurs
EDIT (2):
I have no properties whatsoever in any of my classes and I still get the error.
I just added the properties for test porpouses, to see if a property in a parent class caused the same behaviour, and apparently it doesn't.
Something that is also weird is that when I get the error in the variable, I checked with my intellisense and it finds it...
In order to refer to an instance variable within any object other than self, including super, you must use the structure pointer operator (->). The default scope of an instance variable is protected, which means it can only be accessed within the class it is defined in or a subclass of that class. Since CustomViewController is a subclass of BaseViewController, this scope is sufficient to access the variable using self->_vwHeader, but if the second class you were trying to do this from is not a subclass you will also need to change the scope to either #public or #package.
In summary, change your method call to:
[self->_vwHeader setHidden:NO];
and it should work for any subclasses of the base view controller.
Do a clean and build, and also make sure you are not specifying a specific framework search path in the build settings. If you leave it empty you should get the correct libraries.
well I don't know, should work.
BaseViewController.h
#interface BaseViewController : UIViewController {
UIView *_vwHeader;
}
#property(nonatomic,retain)UIView *_vwHeader;
#end
BaseViewController.m
#synthesize _vwHeader;
CustomViewController.m
#import "CustomViewController.h"
#implementation CustomViewController
- (void)loadView
{
[super loadView];
[self._vwHeader setHidden:NO];
}
#end
I faced similar problem as you. In my case the reason was (strangely!) wrong synthesization of properties in subclass.
Example:
In .h file of subclass you have following declaration
BOOL _flag;
...
#property (nonatomic, assign) BOOL flag;
while in you synthesize the property in the wrong way:
#synthesize flag;
instead of
#synthesize flag = _flag;
Strangely, the compiler does not complain about the wrong synthesization (the properties even work fine!), but raises an error, when I try to access protected fields declared in base class.
Detailed explanation
Here is what my code look like
I have base class (excerpt):
#interface BaseEditionModalController : NSObject
{
DataContext *_dataContext;
}
And I have subclass of it (excerpt):
#interface LocationModalController : BaseEditionModalController
{
MCLocation *_readLocation;
LocationCommModel *_oldLocationCommModel;
}
//This is MCLocation for reading only - from the main application context
#property (nonatomic, retain) MCLocation *readLocation;
#property (nonatomic, retain) LocationCommModel *oldLocationCommModel;
#end
And in the LocationModalController.m I have following wrong declarations:
#implementation LocationModalController
#synthesize readLocation;
#synthesize oldLocationCommModel;
Trying to access _dataContext in LocationModalController produced the error that _dataContext is undeclared.
Changing the synthesization of properties to:
#implementation LocationModalController
#synthesize readLocation = _readLocation;
#synthesize oldLocationCommModel = _oldLocationCommModel;
MAGICALLY SOLVES THE PROBLEM!
Regards
I just stumble upon your method declaration
-(void)loadView { ... }
In a view the first point you can rely that everything is fully initialized is after -(void)viewDidLoad was called. Maybe your code works on the simulator because your Mac is fast enough to cope this speed issue - but your mobile device isn't.
Maybe try this coding:
Your BaseViewController.h file:
#interface BaseViewController : UIViewController {
UIView *_vwHeader;
}
#end
Your BaseViewController.m file:
#import "BaseViewController.h"
#implementation BaseViewController
-(void)viewDidLoad {
[super viewDidLoad];
_vwHeader = [[UIView alloc] init];
}
Your CustomViewController.h file:
#interface CustomViewController : BaseViewController {
}
#end
Your CustomViewController.m file:
#import "CustomViewController.h"
-(void)viewDidLoad {
[super viewDidLoad];
[_vwHeader setHidden:NO];
}
Now your CustomViewController can rely on every instance variable in BaseViewController is correctly instantiated.
The error says that _vwHeader undeclared.
So try by modifying the code in:
CustomViewController.m
#import "CustomViewController.h"
#implementation CustomViewController
- (void)loadView
{
[super loadView];
if(!_vwHeader)
{
_vwHeader = [[UIView alloc]init];
}
[_vwHeader setHidden:NO];
}
#end
It is possible that when you compile for target and for simulation the data members are either protected or private. Probably for target are private by default and this seems to cause the problem. Try out playing with the #private and #protected keywords.
However, I strongly suggest that you use properties even between your super/sub-classes. Having a complex structure is a bit hard to debug. Setting up a property will transfer the access to the data through the getter/setter methods (a breakpoint on #synthesize also works) and you will be able to see in the call stack who is accessing what.
Especially, the syntax #synthesize propertyName = prefixDataNameSufix; allows you to easily adjust your class interface style without having to modify your coding habits.
I had the exact same problem and it turns out that I did not remove an unused iVar/property in the SUBCLASS. Let's call it session. I removed _session from the iVar but I forgot to remove it from the properties, then in the .m file I had this synthesize session = _session. Once I removed them all, I can compile for iOS device without problems.
If you think your superclass is fine, look into your subclass, check your iVars and properties and synthesize section in the .m file
I had this exact problem.
In my case, I was relying on ivar synthesis of a property. That is, I did NOT declare UITextView *textView_, but I did #synthesize textView = textView_;
This builds fine on my iOS Simulator. However, my iOS device build fails, regardless of whether I use llvm or gcc.
When I add the declaration back to my interface:
#interface MyTableViewController : BaseTableViewController {
#private
UITextView *textView_; // this line is important!
}
Everything works fine!
See the answer from tc above. This is a bug in the compiler shipped with sdk 4.2.
Specifically I have seen the same error and if on the same machine I have sdk 4.2 and sdk 4.3 installed the error disappears (even if I compile for 4.2).
If anyone is having this issue after upgrading their tools and devices to iOS10, I had it and found that declaring them as weak, nonatomic in the .h file was the issue. I had never encountered this when doing so before but after removing (weak, nonatomic) from the property declaration, everything worked fine again.