Circular import issues in Objective C & Cocoa Touch
Asked Answered
A

2

6

I have a view controller in Cocoa Touch that detects when the device rotates and switches between the views of the 2 view controllers it has: landscape and portrait.

I want the UIViewControllers in it to be able to access the FRRRotatingViewController, in a similar way as all UIViewControllers can access the UINavigationController they're in.

So I created a UIViewController subclass (FRRViewController) that will have a rotatingViewController property.

I also modified FRRRotatingViewController, so it takes FRRViewControllers instead of plain UIViewControllers.

Unfortunately, when I include FRRRotatingViewController.h in FRRViewController.h (and vice versa), I seem to get into a circular import issue. I don't know how to fix it. Any suggestions?

Here's the code:

//
//  FRRViewController.h

#import <UIKit/UIKit.h>
#import "FRRRotatingViewController.h"

@interface FRRViewController : UIViewController

@end

//
//  FRRRotatingViewController.h

#import <UIKit/UIKit.h>
#import "FRRViewController.h"

@class FRRRotatingViewController;


@protocol FRRRotatingViewControllerDelegate

-(void) FRRRotatingViewControllerWillSwitchToLandscapeView: (FRRRotatingViewController *) sender;
-(void) FRRRotatingViewControllerWillSwitchToPortraitView: (FRRRotatingViewController *) sender;

@end


@interface FRRRotatingViewController : FRRViewController {
    // This is where I get the error:Cannot find interface declaration for
    // 'FRRViewController', superclass of 'FRRRotatingViewController'; did you 
    // mean 'UIViewController'?
}

@property (strong) UIViewController *landscapeViewController;
@property (strong) UIViewController *portraitViewController;

@property (unsafe_unretained) id<FRRRotatingViewControllerDelegate> delegate;

-(FRRRotatingViewController *) initWithLandscapeViewController: (UIViewController *) landscape andPortraitViewController: (UIViewController *) portrait;
-(void) deviceDidRotate: (NSNotification *) aNotification;

@end
Allahabad answered 14/10, 2011 at 12:47 Comment(3)
To import A in B, add @class A in B.h, and #import "A.h" in B.m. Same thing to import B in A.Wat
Why not subclass UIViewController with one new implementation (e.g. FernardosViewController) containing whatever methods you want to be common between subclasses? You'd then have FRRRotatingViewController and FRRViewController derive from FernardosViewController and you could keep references to each other (which would get rid of your circular import problem) in the .h files.Bora
Adding a forward declaration to FRRRotatingViewController in FRRViewController and importing FRRViewController in FRRViewController.h solved it. The compiler would not accept a super class which is a forward declaration.Allahabad
S
19

You can use forward declarations for classes and protocols in headers in most situations to avoid circular import issues, except in the case of inheritance. In FRRViewController.h, instead of importing FRRRotatingViewController.h, can you not make a forward declaration?

@class FRRRotatingViewController;
Sarene answered 14/10, 2011 at 13:2 Comment(0)
P
4

If I'm reading it right your inheritance structure is like so:

UIViewController-->FRRViewController-->FRRRotatingViewController

But you have made the declaration of FRRViewController dependent on importing the file from its subclass, FRRRotatingViewController. The compiler will therefore be importing and reading FRRRotatingViewController before it processes the rest of FRRViewController.h.

I'm assuming you've missed out some of FRRViewController.h since there is no reference to any rotating view controllers in there, but if you are declaring a property in .h of FRRRotatingViewController, then you need to use a forward declaration in FRRViewController.h:

@class FRRRotatingViewController

instead of

#import "FRRRotatingViewController.h"

The latter line, you can put in the first line of your FRRViewController.m file.

Pulcheria answered 14/10, 2011 at 13:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.