19

Is there any way to create a property like this C# property in Objective-C?

public int prop { get; protected set;}

Essentially, I want to make it possible to get the value from outside the class, but to only be able to set the value from within the class.

Jason Baker
  • 192,085
  • 135
  • 376
  • 510

3 Answers3

25

The easiest way to accomplish this is to declare the property as readonly in the public interface for MyClass (i.e. the .h file):

@property (readonly) NSInteger prop;

Then, in .m file for that class, declare a class extension (a category with an empty name). In class extensions, you may redeclare a @property to change its writeability to readwrite:

@interface MyClass ()
@property (readwrite) NSInteger prop;
@end

@implementation MyClass
@synthesize prop;
...
@end

Of course, Objective-C does not enforce access restrictions, so there's nothing stopping some rogue code from calling -[MyClass setProp:]. The compiler will flag this as a warning, however, which is as good as you can get in Objective-C. Unfortunately, there is no standard way to document this "protected" writeable property to subclasses; you'll have to settle on a convention for your team and or put it in the public documentation for the class if it's in a framework that you're going to release.

Barry Wark
  • 107,306
  • 24
  • 181
  • 206
  • Isn't `readwrite` the default? Is it necessary to specify that? – Raffi Khatchadourian Feb 09 '12 at 05:27
  • @RaffiKhatchadourian, `readwrite` is the default, but in a class extension that's overriding a `readonly` original declaration, the `readwrite` is necessary. – Barry Wark Feb 09 '12 at 15:29
  • @BarryWark - you're wrong about that. Try it and see. Since `readwrite` is the default, redeclaring the property redeclares it as `readwrite` by default. That is what it means to be a default. :) – matt Feb 14 '12 at 19:43
  • 3
    Still if you're overriding something else a little explicitness doesn't hurt. – fzwo Mar 07 '13 at 14:47
1

I believe you are looking for the readonly attribute on the @property

@property (readonly) NSInteger prop;

Read more here.

keno
  • 2,956
  • 26
  • 39
  • But then doesn't that require me to access the value behind it directly rather than using the property? – Jason Baker Aug 27 '09 at 01:47
  • yup, if you want to set the value only within the class then you don't really need to use the self.prop syntax ... you would simply reference prop directly. The readonly attribute guarantees that anything outside your class can only get the value but never set it – keno Aug 27 '09 at 01:55
  • This is an incomplete answer; you can redeclare the property in a class extension to make it readwrite. – Barry Wark Aug 27 '09 at 04:30
1

There's no way to make methods @private/@protected in ObjC, these compiler directoves apply only on instance variables. You can, however, declare a static C function in the same file to get a "@private" method.

keno's answer seems like most correct way of achieving this.

arul
  • 13,998
  • 1
  • 57
  • 77