views:

40

answers:

1

I have a data model which is similar to this:

                                          (in another project)
 ________________________________        _______________________
|                                |      |                       |
|  Graph                         |      | DetailedGraph         |
|  GraphListener lstnr           |      | (needs to access foo) |
|  NSString foo                  | <----|_______________________|     
|  ____________________________  | 
| | GraphListener              | |       _______________________
| | Graph enclosing            | |      |                       |
| | (also needs to access foo) | |      | OtherClass            |
| |____________________________| |      | (cannot access foo)   | 
|________________________________|      |_______________________|

Now, my problem is, that GraphListener is supposed to be an inner class, which cannot be done in objc, so I have this solution:

@interface Graph_Listener
{
     @private
     Graph *enclosing;
}
@end

@interface Graph
{
    @package
    NSString *foo;
} 
@end

Now, my problem is, when I come to subclassing Graph, and making the DetailedGraph class, which is in another project, and still needs to access foo, How can I accomplish that (I would prefer not to use properties, because the variable foo shouldn't be accessed outside of GraphListener and DetailedGraph.

+1  A: 

First, I hope your two classes inherit from NSObject and are not root classes. Making a new root in Objective-C on iOS is actually quite difficult unless you keep your instances entirely in isolation from Foundation/UIKit.

Two possible solutions:

  • Don't access the iVar directly. Make and use the accessors, likely via an @property directive. This is the "more correct" solution in that a class implemented in library A should likely not be diddling the ivars of a class from library B directly. Going through the accessor better preserves encapsulation and acknowledges that direct iVar access is an extremely atypical pattern in Objective-C (largely limited only to a class accessing it's own iVars directly).

  • Declare the iVars to be @public and diddle away. Fragile, atypical, and fraught with peril.


Private in Objective-C really means "that compilation unit over there can't see this declaration over here".

Thus, if you want, you can declare a property -- say -- to be publicly readonly and privately readwrite:

Foo.h:

@interface Foo....
@property(readonly) int x;
@end

Foo+Private.h:

@interface Foo()
@property(readwrite) int x;
@end

Foo.m: #import "Foo+Private.h" @implementation Foo @synthesize x; @end

Anything that imports Foo.h will only see that x is readonly. The implementation of Foo will see that it is readwrite. So will anything else that imports Foo+Private.h.

bbum