user798719
user798719

Reputation: 9869

Objective c: i want the automatic memory management of properties, but no access from other classes

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

Answers (2)

David M. Syzdek
David M. Syzdek

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

Jeff Kelley
Jeff Kelley

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

Related Questions