"Cannot find interface declaration error..." after #class - objective-c

I've run into an Objective-C problem that doesn't seem to make any sense to me. I am a relatively well-versed ObjC programmer and understand the whole "forward declaration" concept, but this one has me scratching my head. So here's the deal:
ClassA is a class in my Xcode project that is project-only.
ClassB is a subclass of ClassA which is public and is imported into my framework's header.
I am getting a "Cannot find interface declaration for 'ClassA', superclass of 'ClassB'..." error when building. I have already put the #class ClassA; forward declaration in ClassB.h, but that does not seem to solve the problem. When I change the #class ClassA; to #import ClassA.h, it works fine. However, since ClassA is project-only, dependent projects cannot build ClassB because it cannot access ClassA's source.
Any help would be appreciated and I hope that makes sense. Thanks!

The problem is that you have an infinite loop in your #imports.
The solution: all #imports go in the implementation file and all classes needed are declared in the .h files.

To subclass a class, the superclass's full declaration must be available to the compiler. #class just enables references to instances of said class -- allows for A *foo;.
Subclassing requires more metadata (at least, it did under the legacy runtime -- I think it might be possible to support subclassing without the full super's #interface. Technically possible, but probably not useful.)

I have an answer: You must check your '#import' order. Before you use the superclass it should be imported and compiled.

I had an issue where I was using categories in a superclass method and was getting this inheritance error. Once I moved the categories .h imports to the superclass .m file thing started getting better.

Just carry out all possible headers from .h to .m file of superclass and see which one is the matter of the problem. I'm sure that it's one of common headers used in both classes.

Like #Igor said, the order of imports matters:
I had to change
#import <KeychainItemWrapper/KeychainItemWrapper.h>
#import <Foundation/Foundation.h>
to
#import <Foundation/Foundation.h>
#import <KeychainItemWrapper/KeychainItemWrapper.h>

Related

what is the difference between #import(include) and : (inherit) functionally

I don't seem to understand what the difference between #import (then declaring Pointer to that class) and inheritance as i can both have reference to that super class or the class included..
And, in addition to this topic, view mustn't know about view controller for loose coupling reason. does this mean that view shouldn't #include any controller and having reference to that controller??
I think I'm missing some basic concept that makes me so confused here ..
Thank you for help in advance.
The quick answer to your question is inheritance (:) is a universal object oriented programming principle and inclusion (#import) provides declarations of all symbols used while compiling, which is specific to C like programming languages.
In Objective-C, there is no global symbol space like there is in Java. Each file must include the definition for every symbol used.
This is done by using header files and having interfaces separated from implementations.
The Objective-C compiler only builds .m files, never .h files. The #import statement copies the contents of the .h file into the .m file at build time.
MyFoo.h
#interface MyFoo : NSObject
#end
MyBar.h
#import "MyFoo.h"
#interface MyBar : MyFoo
#end
MyBar.m
#import "MyBar.h"
#implementation MyBar
#end
At compile time only MyBar.m is compiled. To the compiler the #imports have their source dumped into MyBar.m.
How the compiler see MyBar.m
#interface MyFoo : NSObject
#end
#interface MyBar : MyFoo
#end
#implementation MyBar
#end
As you can see, the complier cares about the implementation of MyBar and uses the interfaces as a way to provide context for all the declared symbols.
Importing header file is just referring code written in other file.
while inheritance very different and very powerful concept of Object oriented programming.For good understanding about this please read this.
maybe explaining this in a different way will help you understand..
basically, #import doesnt actually do much, its just putting a header inside your .m file.
inheritance is something completely different, this is when an object takes on the properties and functions of another object, and adds some extra functionality to it. eg, a eagle would inherit from an object, bird, since an eagle is a bird but the eagle kind of defines more than just a bird, aka has sharp talons etc.
now for you to be able to do inheritance, you will have to #import the header of the base type, eg so in your eagle class, you would need to #import "bird.h" to allow you to inherit from it, otherwise the eagle class wont know what a bird is.
the code to do the inheritance would be
//Eagle.h
#import "Bird.h"
#interface Eagle : Bird
//insert properties and functions here that would make an eagle an eagle and not just a bird
#end
hope that helps a bit with explaining the difference
Short answer:-
There are no difference between these two, the only thing is #import is modified style which is being used in Objective-c. But #include is the old C style for importing the class.

Objective-C #interface and #implementation clarification

I'm still fairly new to Objective-C but I'd love to learn more about how it should be done.
I'm building a simple cheat sheet that I'd like to print and put on my office wall as a reminder.
Here's what I have so far:
// Headers (.h)
// Shows what's available to other classes
#interface ExampleViewController : UIViewController
// Declare public methods, ivars &
// properties that are synthesized.
#end
// Implementation (.m)
// Defines the content of the class
#interface ExampleViewController ()
// Class extension allowing to declare
// private methods, ivars & properties that are synthesized.
#end
#implementation ExampleViewController
// Private Properties
// Method definitions
#end
One thing I don't understand is why have both #interface and #implementation inside the implementation .m file?
I get that we can declare private stuff but why not simply throw them in #implementation like:
#implementation ExampleViewController
UIView *view; // private property
- (void)...more code
#end
#1 - Why should I ever use #interface from within my implementation .m file?
#2 - For header .h, why should I ever use #class more than #import?
#import actually gets the whole definition and #class tells the compiler that the symbol is a class. So I just don't see why I should ever use #class?
#3 - Otherwise, is there anything I should be adding somewhere in my .h or .m cheat sheet?
That's not a problem-related question but a more wiki-esque question so we everybody can look it up and completely and quickly understand those concepts as they are very hard to grasp for any newcomer.
Why should I ever use #interface from within my implementation .m file?
Because it's better to clearly separate public and private parts of the class.
For header .h, why should I ever use #class more than #import?
When forward-declaring classes for use in protocols. Like this:
#class Foo;
#protocol FooDelegate
// this wouldn't compile without a forward declaration of `Foo'
- (void)fooDidFinishAction:(Foo *)f;
#end
Otherwise, is there anything I should be adding somewhere in my .h or .m cheat sheet?
That's way too general to be answered in one post.
1 - Why should I ever use #interface from within my implementation .m file?
When you do not intend to expose that interface to any other component. That's certainly the case for private class extensions but may also apply for something like a test which doesn't need a .h file at all because while it does define a class it does not need to expose an interface for any other component to use.
2 - For header .h, why should I ever use #class more than #import?
Invert your question; why should I ever use #import rather than #class?
#class informs the compiler that a class definition of that name will exist to be linked but says nothing about it's interface.
#import makes the class' interface available to you.
A forward declaration requires less work and can allow for faster builds. It is also not always possible to #import a class at all times (as in circular references like #H2CO3's protocol example). If all you need to know is that a class exists then just use the forward declaration. When you actually need to interact with its specific interface (usually in your class' implementation) then you need to #import.
3 - Otherwise, is there anything I should be adding somewhere in my .h or .m cheat sheet?
Unless you intend to actually expose ivars as a public interface (almost certainly not the case) leave them out of your .h and expose only properties instead.
Keep your public interface as simple as possible. Try not to reveal implementation details. However keep it informative enough that users of the class can verify its behavior using that public interface. (I find test driving the design of the class using only it's public interface a good tool for striking this balance.)
Imports and forward declarations expose dependencies. Keep them to the minimum you actually need so that you can understand what the class in question actually depends on.
Delegate protocols and block types are a common part of a class' interface but not part of the #interface. Include them in the .h if they are needed by other classes (e.g. to register callbacks).

What is the empty #interface declaration in .m files used for?

I've started a new iOS 5 project and noticed something new at the top of each .m file
#import "HomeViewController.h"
#interface HomeViewController ()
#end
#implementation HomeViewController
#synthesize ...
Is this extra #interface ... required if I have a separate .h file?
Why did this not show up in pre iOS 5 projects?
Can I use this instead of having a separate .h file?
What is the best practice for this going forward?
That's a class extension. You can use it to make declarations that you don't want to be in the .h file.
This was used by many developers, even before, who manually added the extension in the .m file. So I guess Apple included this in the template because it is widely used and is considered a good practice.
In fact, the .h file should only be used to make declarations that are going to be used from other files. You may have to declare some properties, methods or constants that will only be used inside the .m file. For those declarations, it is better to make them in the class extension.
So to answer your questions:
Is this extra #interface ... required if I have a separate .h file?
No, it is not required but is a best practice.
Why did this not show up in pre iOS 5 projects?
Even if this was a commonly used practice, it was not included in the template.
Can I use this instead of having a separate .h file?
No. The class extension doesn't replace the .h file where you have to declare the "public" interface of your class.
What is the best practice for this going forward?
You should put in the class extension all the declarations that don't need to be visible outside of the .m file.
The interface section in the implementation file allows you to declare variables, properties, and methods that are private, meaning that they won't be seen by other classes.
No, it's not required at all. But I use it as much as possible and only make public those things that other classes need to see.

what does #class do in iOS 4 development?

Is there any difference in doing
#class MyViewController;
rather than doing the normal import of the .h into the appdelegate.h
#import "MyViewController.h"
I've seen some example recently that use the #class way and wondered if there any differences.
thanks.
There is a big difference.
#class MyViewController;
Is a forward declaration for the object MyViewController. It is used when you just need to tell the compiler about an object type but have no need to include the header file.
If however you need to create an object of this type and invoke methods on it, you will need to:
#import "MyViewController.h"
But normally this is done in the .m file.
An additional use of forward declarations is when you define a #protocol in the same header file as an object that uses it.
#protocol MyProtocolDelegate; //forward declaration
#interface MyObject {
id<MyProtocolDelegate> delegate;
...
}
...
#end
#protocol MyProtocolDelegate
... //protocol definition
#end
In the above example the compiler needs to know that the #protocol MyProtocolDelegate is valid before it can compile the MyObject object.
Simply moving the protocol definition above MyObject definition would also work.
#class allows you to declare that a symbol is an Objective-c class name without the need to #import the header file that defines the class.
You would use this where you only need the class name defined for the purposes of declaring a pointer to the class or a method parameter of the class, and you do not need to access any methods, fields, or properties in the class.
It saves a minuscule amount of compile time vs the #import, and it sometimes helps avoid messy include circularity issues.
[And, as rjstelling points out, it's sometimes useful where you have interleaved declarations and you need to "forward declare" something.]

How to declare protocol in separate header file

I have two classes. Both these classes are delegates of each other. This gives me error like "Can not find protocol declaration". After searching on net, I came to the conclusion that, this is the case of cyclic dependency.
To break this dependency the solution they have suggested is to define protocol in another header file. I could not find any tutorial on how to do this and how will it affect my code?
I have a example for you..
#class ClassA;
#class ClassAController;
#protocol CreateClassADelegate
-(void)CreateClassA:(ClassAController *)sender didCreateClassA:(ClassA *)ClassAObj;
-(void)CreateClassACancel:(TSInputController *)sender;
#end
Check #Toro's answer in this previous SO question
UIViewController calling each other's delegate
In case you are using XCode 4 you just creating new file as always, the difference is that you need to choose Objective-C protocol in Cocoa Touch section rather then Objective-C class or UIViewController subclass.
Other approach you may use is to create new Objective-C class and then just delete the .m file manualy and change #interface to #protocol in .h file.