Objective C forward declaration and type compatibility - objective-c

I have code like following:
#import "ViewModelBase.h"
#interface ViewControllerA : UIViewController
#property (nonatomic, strong) ViewModelBase* viewModel;
#end
Then I need to do something like following:
#import "ViewControllerA.h"
#class ViewModelSubclass;
#interface ViewControllerB : ViewControllerA
#property (nonatomic, strong) ViewModelSubclass* viewModel;
#end
Where ViewModelSubclass.h is not supposed to be imported to ViewControllerB.h, only to .m file.
However, ViewModelSubclass is supposed to be subclass of ViewModelBase.
This is done to hide interface of ViewModelSubclass from clients of ViewControllerB.
How do I solve "Property type 'ViewModelSubclass*' is incompatible with type 'ViewModelBAse*' inherited from ViewControllerA" warning?
Or what is a better way to do it?

don't use like this
#import<ViewControllerA.h>
try to use like
#import "ViewControllerA.h"
I think it will solve your problem

Related

incompatible with type id<NSTextFieldDelegate>

I am getting new warning on my old OSX app. I am using OSX 10.10 and I am not quite sure where the problem is. Can someone help?
The actual warning is Property type 'id is incompatible with type id inherited from NSTextField
#import <Cocoa/Cocoa.h>
#import "HyperlinkTextFieldDelegate.h"
#interface HyperlinkTextField : NSTextField <NSTextFieldDelegate>
#property (assign) id <HyperlinkTextFieldDelegate> delegate; <--- warning showing up here
#end
The main implementation is
#interface HyperlinkTextField ()
#property (nonatomic, readonly) NSArray *hyperlinkInfos;
#property (nonatomic, readonly) NSTextView *textView;
- (void)_resetHyperlinkCursorRects;
#end
#define kHyperlinkInfoCharacterRangeKey #"range"
#define kHyperlinkInfoURLKey #"url"
#define kHyperlinkInfoRectKey #"rect"
#implementation HyperlinkTextField
#synthesize delegate;
And the delegate file is
#import <Foundation/Foundation.h>
#protocol HyperlinkTextFieldDelegate <NSObject>
- (void) barLinkClicked: (id) sender;
#end
NSTextField already has a delegate property, and it is typed as id<NSTextFieldDelegate>. Thus, your HyperinkTextField, which is a subclass of NSTextField, inherits this property, just as the error message clearly tells you. You cannot override this inherited property and type it as id<HyperlinkTextFieldDelegate> where that is a different type.

Unknown type name 'AClass' in objective c

In my MyClass.h, I have this:
#import "AClass.h"
#interface MyInterface : UIViewController <UIScrollViewDelegate>
#property (strong, nonatomic) AClass *ptr;
#end
But when I compile it, I get an error saying Unknown type name 'AClass' , did you mean 'BClass'.
What I don't understand it I already have "#import "AClass.h", how can I fix my error?
In AClass.h, I have
#interface AClass : UICollectionViewFlowLayout
#end
And both AClass.h and MyClass.h are in the same directory.
Thank you.
(This answer is obsolete since the question was changed including the displayed code)
It's your headerfile, right? So don't import yourself.
In MyClass.m you need #import "MyClass.h", but not in the header file of MyClass itself.

Cannot find protocol declaration for "XXXX"

I am stuck with this problem. I have the following .h file:
#import <UIKit/UIKit.h>
#protocol MapSettingsViewDelegate
- (void)settingsDidUpdate:(BOOL)scheme;
#end
#interface MapSettingsViewController : UIViewController
#property (nonatomic, assign) id <MapSettingsViewDelegate> delegate;
#property (nonatomic, strong) IBOutlet UINavigationBar *navBar;
#property (nonatomic, strong) IBOutlet UINavigationItem *titleItem;
#property (nonatomic, strong) IBOutlet UITableView *TableView;
- (id)init;
- (IBAction)saveAction:(id)sender;
#end
When I declare the following:
#interface MapViewController : UIViewController <MapSettingsViewDelegate>
The compiler complains with the following message:
Cannot find protocol declaration for 'MapSettingsViewDelegate'
I have the same kind of delegate declaration in other files in the same project that are compiled without a glitch. I spent the last four hours trying to figuring out what I am doing wrong. Cleaning the project does not nothing.
Problem solved. As suggested in this answer, I created a new class with a different name and copied all coded from the previous class. Worked flawlessly. It seems XCode lost track of something.
You are running into preprocessor problems. Both of your classes import each other. I think you can solve this by adding #class below your protocol declaration as shown below; and moving your #import "mapViewController.h" line into MapSettingsViewController.m file. The #class tells the compiler that you will include the class content somewhere else (in the .m file).
Note that, on the top of your MapViewController.h class file you can include #import "MapSettingsViewController.h" just like normal. Hope this help. I ran into the same problem myself earlier.
#import <UIKit/UIKit.h>
#protocol MapSettingsViewDelegate
- (void)settingsDidUpdate:(BOOL)scheme;
#end
#class MapViewController
#interface MapSettingsViewController : UIViewController
#property (nonatomic, assign) id <MapSettingsViewDelegate> delegate;
...
...
Import the MapSettingsViewController.h file

NSObject subclass as a property

I want to use my class as a property in my project. The idea is that i have a class which contains all list ellements. The basic idea i show below in graph:
So i have a myContainerClass object, and i want to do in some other class:
#property (strong,nonatomic) MyContainerClass *obj;
and here i have error! I figure out that i can only use Foundations type as a #property. But Why? What is replacement for doing that (passing an object)?
No, you can use any class you like as a property
#property (nonatomic, strong) MyContainerClass* obj;
is perfectly legal provided that the compiler knows that MyContainerClass is a class. To do that in the header file, the best way is to use an #class forward declaration:
#class MyContainerClass;
#interface SomeOtherClass : NSObject
// method an property declarations
#property (nonatomic, strong) MyContainerClass* obj;
#end
And then include the header file in the implementation:
#import "MyContainerClass.h"
#implementation SomeOtherClass
#synthesize obj;
// other stuff
#end
What is the error you are getting? May be you are not importing MyContainerClass to where you want to use it.
#import "MyContainerClass.h"
Declare a category for an object that you want to add your property to:
#interface NSObject (MyContainerClassAdditions)
#property (nonatomic, strong) MyContainerClass *myContainerClass
#end
Then implement the setter and getter methods using objective c associated object trick:
#import <objc/runtime.h>
#implementation NSObject (MyContainerClassAdditions)
- (void)setMyContainerClass:(MyContainerClass *)myContainerClass {
objc_setAssociatedObject(self, "myContainerClass", myContainerClass, OBJC_ASSOCIATION_ASSIGN);
}
- (MyContainerClass *)myContainerClass {
return objc_getAssociatedObject(self, "myContainerClass");
}
#end

Syntax for resolving incompatible property type on inherited delegate

Some code I inherited has an annoying warning. It declares a protocol and then uses that to specify the delegate
#protocol MyTextFieldDelegate;
#interface MyTextField: UITextField
#property (nonatomic, assign) id<MyTextFieldDelegate> delegate;
#end
#protocol MyTextFieldDelegate <UITextFieldDelegate>
#optional
- (void)myTextFieldSomethingHappened:(MyTextField *)textField;
#end
Classes which use myTextField implement the MyTextFieldDelegate and are called it with this code:
if ([delegate respondsToSelector:#selector(myTextFieldSomethingHappened:)])
{
[delegate myTextFieldSomethingHappened:self];
}
This works, but creates the (legitimate) warning: warning: property type 'id' is incompatible with type 'id' inherited from 'UITextField'
Here are the solutions I've come up with:
Remove the property. This works but I get the warning '-myTextFieldSomethingHappened:' not found in protocol(s)
Drop the protocol entirely. No warnings, but you also lose the semantic warnings if you forget to implement the protocol in the delegate.
Is there a way to define the delegate property such that the compiler is happy?
try:
#property (nonatomic, assign) id<UITextFieldDelegate,MyTextFieldDelegate> delegate;
UITextField has also got property named delegate, but it has another type. Just rename your delegate property to something else.
Found the answer in UITableView.h.
The UIScrollView has property name delegate, and the UITableView has the same name property.
#protocol UITableViewDelegate<NSObject, UIScrollViewDelegate>
// Your code
......
#end
The original problem is that there is no information about MyTextFieldDelegate's inheritance during declaration of delegate property. It's caused by forward declaration of protocol (#protocol MyTextFieldDelegate;).
I've faced the same problem but with protocol declaration in the other .h file. In my case solution was just to #import appropriate header.
In your case you just need to swap the order of declaration:
#class MyTextField;
#protocol MyTextFieldDelegate <UITextFieldDelegate>
#optional
- (void)myTextFieldSomethingHappened:(MyTextField *)textField;
#end
#interface MyTextField : UITextField
#property (nonatomic, assign) id <MyTextFieldDelegate> delegate;
#end