24

I've noticed that some of Apple's examples include both a retain and readonly modifier on properties. What's the point of including retain if no setter gets generated when we're using the readonly modifier?

Example: @property (retain, readonly) NSString *title; from the AnimatedTableView sample.

jscs
  • 63,694
  • 13
  • 151
  • 195
Matt
  • 1,710
  • 3
  • 14
  • 15

2 Answers2

36

Or, more specifically, (readonly, retain) enables a pattern like this:

Foo.h:

@interface StuffHolder:NSObject
@property(readonly, retain) MyStuff *stuff;
@end

Foo.m:

@interface StuffHolder()
@property(readwrite, retain) MyStuff *stuff;
@end

@implementation StuffHolder
@synthesize stuff;
@end

The end result is a property that is publicly readonly while being readwrite within the implementation and for whom both setter and getter are synthesized automatically by the compiler.

A warning could be generated in the case of no (readwrite, retain) override in the class extension -- something akin to statement without an effect -- but it would be more confusing than beneficial. There are also a whole slew of different edge cases across the combinations that would equally warrant a warning, but don't really indicate an actual problem. The decision was made to largely accept the various patterns without complaint for simplicity's sake (since they aren't correctness issues).

bbum
  • 162,346
  • 23
  • 271
  • 359
  • It's advertised as read-only but it will still be writeable if the compiler has generated a setter for it, wouldn't it? – dreamlax Feb 23 '10 at 23:43
  • 1
    If someone were to write the code to call the setter, sure, but without also declaring the method somewhere, they'll see a warning... – bbum Feb 24 '10 at 00:06
  • "Public" readonly properties (declared in the header) and "private" retain properties (declared in the source file) are no longer supported (with Xcode 3.2.3 - iPhone SDK 4 and GCC 3.2) error: synthesized properties 'x' and 'y' both claim ivar 'z' – Felix Jul 15 '10 at 07:56
  • 2
    They most certainly are supported. Please file a bug if you are finding a particular pattern that isn't working (that should be)! http://bugreport.apple.com/ – bbum Jul 15 '10 at 18:03
17

You can include a second, private readwrite declaration in a class extension. The memory management scheme for all references needs to match IIRC, so you get silliness like "readonly, retain".

Chuck
  • 234,037
  • 30
  • 302
  • 389
  • 3
    It isn't entirely silly; the matrix of modifiers vs. @synthesize is such that the getter's code **can** change. Trying to suss out exactly which modifiers should be able to be added vs. which should #warn would rife with minutia and hard to ultimately understand. Better to simply go with "must be same except readonly->readwrite". – bbum Dec 19 '09 at 19:28