4

Having just started doing iPhone programming with iOS 7, I find properties difficult to grasp past the simple. It's difficult to discern what is relevant, and what is no longer relevant as one discovers documentation about them (official or otherwise), since things have evolved over the last few releases.

I get the basic patterns, e.g.

@property (strong, nonatomic) NSString *name;

I know I should refer to _name if I want to do direct access, but having done the property, I can/should do self.name, and that that will turn into things like [self setName: ...] or [self name] and that I can even implement these to create side effects, and that I get KVO behavior from them.

The new ground I wanted to venture into today, was having a virtual property, so that I can use dot notation when accessing/setting, but that I will define the access/set methods. More specifically, I have an object with the following "normal" properties:

@property (strong, nonatomic) NSDate* started;
@property (strong, nonatomic) NSDate* paused;
@property (assign, nonatomic) BOOL repeat;

I want to add a status property that will return/assign an NSDictionary derived from those values. The "methods" part I get how to write:

- (NSMutableDictionary*) status {
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    if (self.started != nil)
        dict[@"started"] = self.started;
    if (self.paused != nil)
        dict[@"paused"] = self.paused;
    if (self.repeat)
        dict[@"repeat"] = @(YES);
    return dict;
}

and

- (void) setStatus: (NSDictionary*) doc {
    self.started = doc[@"started"];
    self.paused = doc[@"paused"];
    self.repeat = doc[@"repeat"] != nil;
}

What I don't know, is what magic sauce I add where, so that I can just use self.status and self.status = @{}? In iOS 7 / Xcode 5. I don't need this virtual/composite property to be KVO'able.

Rafał Sroka
  • 39,540
  • 23
  • 113
  • 143
Travis Griggs
  • 21,522
  • 19
  • 91
  • 167

2 Answers2

15

Just add

@property (strong, nonatomic) NSDictionary* status;

to the interface. Since you have implemented both setter and getter for the property, the compiler with not create any accessor methods (and no backing instance variable _status), and your methods are called.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • But I don't want/need any memory associated with it. I don't need/want a _status ivar magically appearing. Won't this happen if I do as you suggest? – Travis Griggs Feb 21 '14 at 19:46
  • @TravisGriggs: No (I just added that to the answer). If *both* accessors are implemented, no ivar is created by the compiler for that property. – Martin R Feb 21 '14 at 19:47
  • So what does trigger the compiler to add the backing variable? How does it discern when to do and not to do that? – Travis Griggs Feb 21 '14 at 19:48
  • 6
    @TravisGriggs: The compiler creates the ivar if not all required accessor methods are provided. For a read-only property: If no getter is provided. For a read-write property: If not both getter and setter are provided. – Martin R Feb 21 '14 at 19:49
  • OK, lightbulb flickering on I think. Accept imminent. As aside, when *would* I use any of the other special keywords anymore (i.e. dynamic, synthesize, etc)? Or are they all obsolete now? – Travis Griggs Feb 21 '14 at 19:52
  • 1
    @TravisGriggs: You can use `@synthesize prop = _prop;` if you have provided all required accessor methods, but *want* a backing ivar. - And nothing has changed with respect to `@dynamic`. It indicates that the accessors will be provided at *runtime* (for example, Core Data dynamically created accessor methods). – Martin R Feb 21 '14 at 19:56
3

Why not just add a property:

@property NSMutableDictionary *status;

You can think of a property declaration as being equivalent to declaring two dot-accessor methods.

There is an ongoing discussion about the merits of dot notation vs. message notation. You might want to have a look: Dot notation vs. message notation for declared properties

Community
  • 1
  • 1
Rafał Sroka
  • 39,540
  • 23
  • 113
  • 143