I'm fighting with something and I don't find any satisfying solution.
I have a class with a "myMutableArray" member.
I would like the class to manage itself adding and removing items from the array, so I don't want any other class being able to access the member and call NSMutableArray methods on it.
In an ideal situation, I would like to have a private getter (to be able to call self.myMutableArray) and a public setter for this member.
Do you know how I may achieve this ?
In other words :
be able to call
- [oneInstance setMyMutableArray:thisArray]; // set
- oneInstance.myMutableArray = thisArray; // set using setter
- thisArray = oneInstance.myMutableArray; // get
- [oneInstance addItem:anItem]; // add
not being able to call :
- [oneInstance.myMutableArray add:etc...] // add
be able to call
- self.myMytableArray = [NSMutableArray array]; // set
- thisArray = self.myMytableArray ; // get
Thank you.
@interface Foo : NSObject
@property(readonly, retain) NSArray * myReadonlyArray;
- (void) addItem: (Item *) anItem;
- (BOOL) publiclyDoSomething;
@end
@interface Foo()
@property(readwrite, retain) NSMutableArray * myMutableArray;
- (void) doSomethingInPrivate;
@end
@implementation Foo
@synthesize myMutableArray = myMutableArray_;
- (void) addItem: (Item *) anItem
{
// assuming myMutableArray_ was already iniitialized
[self.myMutableArray addObject: anItem];
}
- (NSArray *)myReadonlyArray
{
return self.myMutableArray;
}
... rest of methods (including the public/private) implementations ...
@end
Some details:
Objective-C has "instance variables", not "member variables".
The above defines a public getter and private setter that is synthesized automatically. For clarity's sake, I also added a public method and a private method.
"Public" and "private" in Objective-C are defined entirely by visibility to the compiler. The setter for myMutableArray
and the method doSomethingInPrivate
are only private because their declarations in an @interface
cannot be imported.
self.myMutableArray
and [self myMutableArray]
do the same thing; the .
syntax is merely short hand for an equivalent method call (with a few edge case details beyond this question)
@property
in the @interface
is purely short hand for method declarations (with a bit of extra metadata).
@interface Foo()
is a class extension and not a category. It exists for exactly the purpose demonstrated above; to extend the @interface
of a class with additional declarative information whose scope should be limited. It can appear in a header file that, say, you only import in your library's implementation to create library-private functionality.
@dynamic
is used when you neither @synthesize
an @property
nor provide a conventional method implementation. It is not needed otherwise!
I'm probably forgetting something.