Reputation: 9869
I've kind of been confused about properties. Some people say to always use setters and getters for ivars, even within the ivar's class. So if "name" is an ivar, when referring to it, one should always use "self.name". Always. Even if you're in the same class that "name" is declared in.
First, is that correct advice? Second, what if I wish to reap the automatic memory management that comes with declaring "name" as a property and synthesizing it, but I don't want to give other classes access to change "name"? I guess it would be sort of a private property?
Thanks!
Upvotes: 0
Views: 134
Reputation: 15788
For ivars which are accessed externally, I generally use properties to access the ivar from within the class, for ivars which are only used internally (usually BOOL, NSUInteger, NSInteger, etc), I use the ivar directly. I do however access an consistently within the class (i.e. if I'm using a property to access it, I always use a property).
For the second part of your question. You can create a readonly property in the class's interface definition and within the same file as the implementation create a category with the read-write property. For example:
MyClass.h
@interface MyClass : NSObject
{
NSString * name;
}
@property (nonatomic, readonly) NSString * name;
@end
MyClass.m
@interface MyClass()
@property (nonatomic, retain) NSString * name;
@end
@implementation MyClass
@synthesize name;
-(void)dealloc
{
[name release];
[super dealloc];
return;
}
@end
Keep in mind, that although another class accessing the method -setName:
may cause compile warnings or errors, another class may still call -(id)performSelector:withObject:
with without an error.
For instance:
MyClass * test = [[MyClass alloc] init];
test.name = @"David";
is functionally the same as:
MyClass * test = [[MyClass alloc] init];
[test performSelector:@selector(setName:) withObject:@"David"];
Upvotes: 2
Reputation: 19071
Yes, you should always try to use the property accessors when possible. Using ARC alleviates these concerns somewhat, but it's still good style. As for your second question, you can declare the property as readonly
in the public header file and redefine it in a class extension:
In MyClass.h
:
@interface MyClass : NSObject
@property (strong, readonly, nonatomic) id foo;
@end
In MyClass.m
:
@interface MyClass()
@property (strong, readwrite, nonatomic) id foo;
@end
@implementation MyClass
@synthesize foo = _foo;
// The rest of your code goes here.
@end
This will allow you to call [self setFoo:foo]
all day inside of MyClass
’s implementation, but not other classes.
Upvotes: 4