Avoiding cyclic header imports

  • I have two classes, and a model object - RSPlugin, RSExpression, and RSRule - which share the same data model.
    I have thought to have the classes provide a method which can be used to initialize the RSRule object so:

    RSRule * rule = [[RSRule alloc] init];
    [rule loadFromPlugin: currentPlugin];

    where -[RSRule loadFromPlugin:] copies the values to the rule. This requires however that RSRule #imports the RSPlugin header.

    I also would like to maintain symmetry by having RSPlugin import the values of RSRule, for purposes of round-tripping to the UI (plugin reps the UI for a rule instance).  Obviously, this would require RSPlugin to #import RSRule's header.  Xcode doesn't like this one bit.

    The same sort of reciprocal data-swapping interface would be wanted for the RSExpression side of the chain.

    I imagine this is such a commonplace sort of relationship that there must be a standard approach (or perhaps several approaches) to solving it.  My first stab at it was to try and provide the interfaces as categories but I ran into a similar issue with circular imports.

    Anyone got a pointer to a Comp Sci 101 style description of how to avoid this?  Thanks for your time.

    ~ Erik
  • On Jul 10, 2012, at 5:01 PM, Erik Stainsby <erik.stainsby...> wrote:

    > where -[RSRule loadFromPlugin:] copies the values to the rule. This requires however that RSRule #imports the RSPlugin header.
    >
    > I also would like to maintain symmetry by having RSPlugin import the values of RSRule, for purposes of round-tripping to the UI (plugin reps the UI for a rule instance).  Obviously, this would require RSPlugin to #import RSRule's header.  Xcode doesn't like this one bit.

    You need to #import the other class's header in the .m file, but not in the .h file. There you can just declare it like "@class RSRule;". That should be enough to avoid circular #imports (and by the way, greatly reduce the number of #imports in your headers, which is good for reducing build times.)

    About the only times you need to #import another header are if it declares the superclass of an @interface, or a protocol you're implementing, or some typedef or enum that's used in the API.

    —Jens
previous month july 2012 next month
MTWTFSS
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
Go to today