12

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!

6 Answers 6

37

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.

Sign up to request clarification or add additional context in comments.

Comments

10

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.)

5 Comments

Hmm, I figured as much. However, that makes me unsure what to do here. I suppose the only route I have left is to make the superclass public and simply document that using the superclass is not advised.
Ah, yes. An abstract superclass. I'd suggest you read about Class Clusters because they perpetuate a similar design pattern.
Unfortunately, I don't believe class clusters address this issue. Class clusters hide subclasses that provide specific functionality. I am trying to hide the superclass while still making the subclasses publicly available. In any case, thanks for the insight!
Well... you can always implement key methods in the abstract super and @throw an exception when called. "Subclass responsibility" is the name of the pattern and I described it here: friday.com/bbum/2009/11/21/calling-python-from-objective-c
After getting a solution working and having time to mull over this problem again, I believe I have come up with an equitable solution. The "superclass" should actually be converted into an independent object that the "subclasses" then hold as a field and use to expose functionality and internal state that dependent projects will not have access to otherwise. Hope that makes sense!
7

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

Comments

1

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.

Comments

1

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.

Comments

0

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.