Stephen F Roberts
Stephen F Roberts

Reputation: 280

"Proper" way to define a class - Properties vs Methods

This is an observation and a question:

I am loading some json data into a class (json already converted into an NSDictionary). The values will be read-only from the outside:

@interface Checklist
-(id)initWithJSON:(NSDictionary *)json;
-(NSInteger)checklist_id;
-(NSString *)checklist_name;
etc....
@end

With the corresponding method bodies in the .m file.

As a test, I created a class for another data element:

@interface ChecklistItem
-(id)initWithJSON:(NSDictionary *)json;
@property (readonly) NSInteger item_id;
@property (readonly) NSString *item_name;
@end

Functionally, the two classes have similar methods in the @implementation. In both cases they basically pull the appropriate value from the json and return the result. And as far as the rest of the program was concerned, the two approaches seem to be interchangeable.

So my question is:

Which approach is the best one to use?

I find either way equally readable and so far I can not find any code-reason to prefer one way over the other. I can kind of see the second option as nice since it kind-of documents the json.

Upvotes: 0

Views: 104

Answers (5)

ethyreal
ethyreal

Reputation: 3669

this is a subjective question and you'll get nothing but opinions back, but here is mine:

the read only properties will just write the getters for you. if you don't write a private read write propertly in your .m file or wherever and just set the ivar's directly you don't even get the will/did change value for key calls and will have to call those yourself also.

@interface ChecklistItem ()
    @property (readwrite) NSInteger item_id;
    @property (readwrite) NSString *item_name;
@end

To access them KVO complient inside the object you'll have to do:

self.item_id = 13;

And not:

_item_id = 13;

Of course you could just have getter methods:

-(NSInteger)checklist_id;
-(NSString *)checklist_name;

And just wrap all changes in in your KVO methods:

[self willChangeValueForKey:@"checklist_id"];
_item_id = 13;
[self didChangeValueForKey:@"checklist_id"];

it's just a coding style choice, and sometimes leveraging what the compiler will write for you. but either option works the same.

Upvotes: 0

Adam Waite
Adam Waite

Reputation: 18855

This is less important now that ARC will clean up memory which would have been managed inside the setter but this is still very much best practice. The performance overhead of calling a setter method is also negligible compared to the safety gained from always going through the setter.

Upvotes: 0

vikingosegundo
vikingosegundo

Reputation: 52237

You should use properties, they come in handy once you use KVO.

Also you can define public readonly properties and overwrite them in a class extension with a readwrite property that is only usable in the same class. If you try to achieve something similar you will have to deal with private helper methods — the code gets ugly.

Upvotes: 3

Kudit
Kudit

Reputation: 4379

If the values are read only, I'd think you'd want them as methods rather than as read-only properties to avoid any confusion that the values might be able to be set. Unless of course you want the subscribers to be able to use the dot notation for accessing the properties, but if you're just returning the values in the NSDictionary, the method form would be better as you're not keeping around another copy of the data.

Upvotes: -1

Jim
Jim

Reputation: 73966

-(NSInteger)checklist_id;
-(NSString *)checklist_name;

This isn't standard Objective-C naming. If you want to do things properly, follow the platform conventions. Apple document this in their coding guidelines documentation.

Which approach is the best one to use?

They are equivalent as far as Objective-C is concerned. The property syntax expresses your intent at a higher level than manually creating the methods, so I would prefer that approach. It's also less code.

Upvotes: 3

Related Questions