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 :
I would like other classes
开发者_如何学运维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
I would like my class
be able to call
- self.myMytableArray = [NSMutableArray array]; // set
- thisArray = self.myMytableArray ; // get
Thank you.
Is there any reason you need the public setter? It sounds like the class itself owns the array. You'd probably be better off not providing any public property access to the field, and making a public method which copies the values into your private field.
// public interface, in the .h file
@interface MyClass : // superclass, protocols, etc.
- (void) setSomething:(NSArray *)values;
@end
// private interface, not in the .h
@interface MyClass ()
@property (/* attributes */) NSMutableArray *myMutableArray;
@end
@implementation MyClass
@synthesize myMutableArray = myMutableArray_;
- (void) setSomething:(NSArray *)values
{
[self.myMutableArray setArray:values];
}
@end
Foo.h
@interface Foo : NSObject
@property(readonly, retain) NSArray * myReadonlyArray;
- (void) addItem: (Item *) anItem;
- (BOOL) publiclyDoSomething;
@end
Foo.m
@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 methoddoSomethingInPrivate
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.
精彩评论