views:

119

answers:

2

I tried to make a private property in my *.m file:

@interface MyClass (Private)
@property (nonatomic, retain) NSMutableArray *stuff;
@end

@implementation MyClass
@synthesize stuff; // not ok

Compiler claims that there's no stuff property declared. But there's a stuff. Just in an anonymous category. Let me guess: Impossible. Other solutions?

A: 

You don't want a private @property. The whole point of properties is to allow access to an instance variable or internal state from outside of your class. It's not supported because it doesn't make sense.

If you're trying to do this then perhaps you need to refactor your class structure, and think about what part of your code should understand the implementation and what parts should just be using the class's public API.

EDIT -- OK I admit it is possible, as per other answer and also http://swish-movement.blogspot.com/2009/05/private-properties-for-iphone-objective.html

I'm still highly suspicious of using private @properties because of the confusion and bad code that it can cause. As jbrennan says, you can use the dot-syntax without a property, which means that just looking at your code you can't tell if self.foo = bar is going to just directly set the variable and that's it, or else, it might call a setter which has all kinds of funky side effects. That's just asking for confusion and bugs down the road.

Name your ivars _something and set them directly, or call a method so that it's clear that side-effects can happen.

sbwoodside
Actually I use private properties all the time. You still can benefit from having the compiler synthesize your setters/getters and you also can use dot-syntax if you like (I do). (PS: I know you can use dot-syntax without a property, but it's not recommended).
jbrennan
+7  A: 

You want to use a "class extension" rather than a category:

@interface MyClass ()
@property (nonatomic, retain) NSMutableArray *stuff;
@end

@implementation MyClass
@synthesize stuff; // ok

Class extensions were created in Objective-C 2.0 in part specifically for this purpose. The advantage of class extensions is that the compiler treats them as part of the original class definition and can thus warn about incomplete implementations.

Besides purely private properties, you can also create read-only public properties that are read-write internally. A property may be re-declared in a class extensions solely to change the access (readonly vs. readwrite) but must be identical in declaration otherwise. Thus you can do:

//MyClass.h
@interface MyClass : NSObject
{ }
@property (nonatomic,retain,redonly) NSArray *myProperty;
@end

//MyClass.m
@interface MyClass ()
@property (nonatomic, retain, readwrite) NSArray *myProperty;
@end

@implementation MyClass
@synthesize myProperty;
//...
@end
Barry Wark