2

I have come to find that many of the times in which I want to have a synthesized readonly property, I merely implement the getter method of that property in terms of other variables with no need for an ivar, for example (Note: I am defining ivars in the interface because I am using OmniGraffle UML software and it does not recognize ivars auto-generated by synthesized properties):


@interface Editor : UIView {
    BOOL _wordWrap;
    BOOL _showLineNumbers;
    NSDictionary *_options;
}

@property (nonatomic) BOOL wordWrap;
@property (nonatomic) BOOL showLineNumbers;
@property (nonatomic, copy, readonly) NSDictionary *options;

@end


@implementation Editor

@synthesize wordWrap = _wordWrap;
@synthesize showLineNumbers = _showLineNumbers;
@synthesize options = _options;

- (NSDictionary *)options {
    return @{   
                @"WordWrap"         : [NSNumber numberWithBool:self.wordWrap],
                @"ShowLineNumbers"  : [NSNumber numberWithBool:self.showLineNumbers],
            };
}

@end

In the above Editor class, is it necessary for me to define the _options ivar in the header definition and more importantly does the auto-generated ivar take up memory or space in the symbol table? Also, would it be more efficient to use copy, retain, or no value in this case? Just curious.

rolling_codes
  • 15,174
  • 22
  • 76
  • 112

1 Answers1

4

First: stop putting your ivar declarations in your @interface. They belong in your @implementation. See this answer for a detailed explanation.

Anyway, given what you've written, your @synthesize options = _options has no effect.

That @synthesize has two possible effects:

  1. It adds an instance variable named _options, if your class doesn't have one.

  2. It generates a getter method, options, that returns the value of _options, if your class doesn't have a method named options.

Since you manually defined the instance variable and the getter, the @synthesize does nothing. You can remove it entirely without changing the meaning of your program.

Specifying copy on a readonly property has no effect. The copy and retain (or, more properly under ARC, strong) attributes only affect the generated setter method, and the compiler doesn't generate a setter for a readonly property. (If you change the property to readwrite in a class extension, then copy matters.)

Yes, the _options ivar takes up both memory (for each instance of Editor) and space in the symbol table. Since you're not using the _options ivar, you should delete it entirely. You should also delete the @synthesize entirely, so the compiler doesn't generate the _options ivar for you.

Community
  • 1
  • 1
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • I write the ivars because I use OmniGiraffe to generate UML's – rolling_codes Jul 09 '14 at 20:31
  • Nevertheless it consumes memory. – rob mayoff Jul 09 '14 at 20:32
  • I can still access the property by using self.options right? – rolling_codes Jul 09 '14 at 20:33
  • 2
    Yes. When you write `self.options`, it is exactly the same as writing `[self options]`: it sends the `options` message to `self`. – rob mayoff Jul 09 '14 at 20:34
  • Okay I followed your advice in the linked answer you posted but when I get into setter methods for text `- (void)setText:(NSString *)text` when calling `self.text = text` I get an error unless I declare `@synthesize text = _text;` instead of `@synthesize text;` before it – rolling_codes Jul 09 '14 at 20:43
  • 1
    The answer may be different if you are using a `readwrite` property. Update your question to include the details of your `text` property, how you're trying to use it, and what precise error you're getting. – rob mayoff Jul 09 '14 at 21:27