tags:

views:

77

answers:

3

Hello. I'm new to iOS development and am running into an issue with my header files. I'm running into a circular dependency issue with my header files. My application delegate class contains a pointer to my view controller, since I have to set one of the view controller's properties in my didFinishLaunchingWithOptions method...

//appDelegate.h     //DISCLAIMER: THIS IS UNTESTED CODE AND WRITTEN ON THE FLY TO ILLUSTRATE MY POINT
#import <UIKit/UIKit.h>
#import "MyViewController.h"

@interface appDelegate

     NSManagedObjectContext *managedObjectContext;

     MyViewController *viewController;
     BOOL myFlag;

@end

//appDelegate.m
@implementation appDelegate

- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
     viewController.managedObjectContext = self.managedObjectContext;
     .
     .
     .
}
@end

And in my view controller, I reference the "myFlag" property, that's in my app delegate...

//MyViewController.h                                        
#import "appDelegate.h"     //<---circular dependency, causing "Expected specifier-qualifier-list before MyViewController" errors in my appDelegate header file

@interface MyViewController: UIViewController
{
     NSManagedObjectContext *managedObjectContext;
}
@end

//MyViewController.m
@import "MyViewController.h"

@implementation MyViewController

- (void)viewWillAppear:(BOOL)animated
{
     [super viewWillAppear:animated];

     ((appDelegate*)[[UIApplication sharedApplication] delegate]).myFlag = NO;
}

@end

But in order to access the "myFlag" property in my app delegate, I need to import the app delegate's header file. This is what's causing the circular dependency. Not sure how to resolve this, has anyone run into this?

Thanks in advance for your help!

+4  A: 

Don't #import "MyViewController.h" in appDelegate.h. Instead, forward-declare the class.

@class MyViewController;

@interface appDelegate

     NSManagedObjectContext *managedObjectContext;

     MyViewController *viewController;
     BOOL myFlag;

@end

Also, you don't need to #import "appDelegate.h" in appDelegate.h if you need is to reference the myFlag property in the implementation. Instead, import it in the appDelegate.m file.

KennyTM
+1  A: 

Did not read everything, but you can do forward declarations with @class. Usually how I solve circular dependencies.

Erik B
+1  A: 

@class is the syntactic approach you're looking for.

Many coders look to avoid this circularity (which couples your classes in two directions, meaning your view controller can only be used in circumstances where the app delegate has that BOOL). There are a few ways you can do this:

  • Move the state variable to a singleton
  • Have the view controller fetch the value through an interface that the delegate implements
  • Key-Value Observing (which your app delegate would configure on your view controller)

For small projects this kind of dependency is probably not really a problem, but as project size grows and the desirability of code reuse grows, clean functional separation becomes more and more valuable.

Seamus Campbell