1

When I use assign when declaring a synthesized propery, does ARC automatically still create a matching ivar to it? My property is as follows

@property (nonatomic, assign) NSString *text:

And

- (NSString *)text {
    return self.label.text; // label is a UILabel
}

- (void)setText:(NSString *)text {
    self.label.text = text;
}

I never have any use for the automatically generated _text ivar; does the compiler still create this ivar when I omit @synthesize text = _text or does the unused ivar just persist in the memory unused?

rolling_codes
  • 15,174
  • 22
  • 76
  • 112

3 Answers3

4

Do not use assign this way. It probably won't matter in this particular case, but it's extremely confusing to the caller, and it'll generate very bad bugs if you ever change the implementation.

The fact that you implemented the getter and setter means that the compiler won't generate an ivar. That has nothing to do with what memory-management attribute you use. Use strong here because that's what you implemented. Your header should match your implementation.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • But won't the ivar still appear in the symbol table? – rolling_codes Sep 03 '14 at 13:00
  • 1
    It shouldn't. Do you see one? A better question is whether it will show up in the list of ivars from `class_copyIvarList()`, but it shouldn't be there either. If it is, you should open a compiler defect. You can also look at the assembly output (Choose "Assembler" in the assistant editor pane) and see for yourself. It shouldn't be there. – Rob Napier Sep 03 '14 at 13:03
  • 1
    You can also more simply prove it to yourself by trying to access `self._text`. This should fail to compile. – Rob Napier Sep 03 '14 at 13:04
  • What do you mean by strong implementation? What does assign implementation look like? – rolling_codes Sep 03 '14 at 16:23
  • The `strong` implementation retains the new value and releases the former value. The `assign` implementation does no memory management. – Rob Napier Sep 03 '14 at 17:24
  • But your implementation does do memory management. You call a setter (`[UILabel setText:]`); actually it's a `copy` setter, so you should really indicate `copy` in your interface since that's what's happening. This is just information to the caller; it doesn't cause the compiler to add an implementation. You already wrote the implementation. – Rob Napier Sep 04 '14 at 13:03
1

The ivar is created automatically for you only if you haven't implemented your property yourself. And the @synthesize text = _text; is done automatically unless you provide your own implementation for getter and setter or synthesize the property to some other variable. For example:

@synthesize text;

The above will synthesize text property to text variable.

As for using assign instead of copy, that will theoretically use less memory, but is dangerous at the same time. If you use mutable strings, if you change the string value after assigning it to a property, the property value will also change, which is not what you want in most cases.

Adam
  • 26,549
  • 8
  • 62
  • 79
  • 1
    "unless you provide your own implementation for getter and setter." He did implement the getter and setter. The ivar won't be created. – Rob Napier Sep 03 '14 at 13:01
1

Are you worried about 4-8(32/64 bit pointers) bytes of extra allocations per instance? Using assign, weak or strong strong will not change the memory footprint. No matter what you use the string is not copied the reference always points to the same instance. The difference is only that the assig, weak do not increase the ref count of the object so by omitting the ivar you only "save" 4-8 bytes depending on what architecture you use.

Peter Segerblom
  • 2,773
  • 1
  • 19
  • 24