Objective-C variable with multiple permissions
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
.
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.
精彩评论