I have a singleton class called DataManager. This class is used by several other classes to deal with loading and saving plist files.
I am adding the ability for DataManager to save screenshots as well as plist files. This requires me to load the view I wish to take a screenshot of. The view I’m loading comes from a controller that imports DataManager.
Obviously this is circular dependency, so I used:
@class GardenView;
However, this resulted in the following errors:
- Receiver ‘GardenView’ for class message is a forward declaration
- Receiver type ‘GardenView’ for instance message is a forward
- declaration Property ‘bounds’ cannot be found in forward class
- object ‘GardenView’ Property ‘layer’ cannot be found in forward
class object ‘GardenView’
This seems like it can’t find properties inherited from the UIView superclass. Is this true of forward class declarations?
If I use the standard #import instead of @class, I get:
- Parse Issue: Expected A Type
for the methods in GardenView referencing Plant (which I am importing just fine):
- (void) addPlantToView: (Plant*) plant;
- (void) addPlantToGarden: (Plant*) plant;
- (void) addPlantToViewAndGarden: (Plant*) plant;
The Plant class DOES import the DataManager, but if I change it to @class, I get:
- No known class method for selector ‘sharedDataManager’
What is the solution for this problem? The class method is there in the header file (+sharedDataManager). Am I doing something completely wrong?
You haven’t made it clear where exactly you’re doing the imports vs
@class. And I think that’s causing confusion. Here’s what you want to do:@class Plant@class GardenView#import "Plant.h"#import "GardenView.m"This breaks the circular dependency in the headers, but still allows the implementations to see the full information of the dependent class.
Now the reason why
@classalone isn’t sufficient is because all@class Foodoes is it tells the compiler “There exists a class named Foo”, without telling it anything at all about the class. The compiler doesn’t know its methods. It doesn’t know its superclass. All it knows is if it sees the tokenFoo, then that represents a class type. You can use this in header files so you can refer to the class in arguments and return types, but in order to actually do anything with values of that type you still need the full#import. But you can put that#importin the .m file without any problem.The only time you need
#importinstead of@classin your header is if you want to inherit from the class in question. You cannot inherit from forward-declared classes, so you need the full#import. Of course, you may also need the#importif you need access to other types defined in the same header (e.g. structs, enums, etc.), but that’s less common in obj-c.