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.
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.
-(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.
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.
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.
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.
Related
I am studying Big Nerd Ranch's Objective C programming book.
I saw a code like below:
#interface BNREmployee : BNRPerson
{
NSMutableArray *_assets;
}
#property (nonatomic) unsigned int employeeID;
#property (nonatomic) unsigned int officeAlarmCode;
#property (nonatomic) NSDate *hireDate;
#property (nonatomic, copy) NSArray *assets;
-(double)yearsOfEmployment;
-(void)addAsset:(BNRAsset *)a;
-(unsigned int)valueOfAssets;
In this code, why do you declare NSMutableArray *_assets under the interface? How is this different than declaring it as a property, and what purpose does it serve?
Lastly, I see there is a NSArray *assets in a property. Is this basically same as NSMutableArray *_assets?
Here, you're declaring an instance variable named _assets:
#interface BNREmployee : BNRPerson {
NSMutableArray *_assets;
}
You can now use this variable within the implementation of your class:
_assets = #[ #1, #2, #4 ].mutableCopy;
NSLog(#"The Answer is %#.", _assets[0]);
However, instance variables are private in Objective-C, which is good if you do not want anything else to access it. However what if you need other classes to be able to access and/or change assets?
For the most part you will want to use a property iVar.
By using a property we automatically create the setters and getters, meaning this can be overridden for customization and used by other classes (if placed in the header .h file).
#property (nonatomic, assign) NSMutableArray *assets;
NSMutableArray is just the mutable (editable) counterpart to NSArray, it means we can modify the values of the array by inserting new ones, deleting old ones and moving the indexes around.
I'm not sure why they did that but as a general good practice, you shouldn't do that yourself. The header file should be reserved for the public interface of the class. Only put things in there that callers and users of that class actually need to see, which will generally be properties, methods, and perhaps extern constants.
Then the question becomes in the implementation whether to use a property or a regular instance variable. This is largely preference based. Some people declare properties for everything and don't use plain ivars at all. Others use ivars for everything and only properties when they want to declare a custom setter/getter for the variable in question. I am in the latter camp but it is arguable that is clearer and easier to read if everything is just a property.
edit
I misread the code. What I say above stands normally, but what they are doing there is exposing an API that is different than the underlying data. Editing my answer now.
When you declare a property without a custom #synthesize and without having overridden both the setter and getter if they are applicable, an underlying variable is created with the underscore in front. What they are doing here is returning an NSArray in the public API to ensure the internal variable is not modified while internally using an NSMutableArray.
I would say that in general though, that variable declaration (NSMutableArray *_assets;) should still go in the implementation file. The caller should probably not need to know that it is mutable under the hood.
There are actually a lot of existing questions touching upon this already. Here is a search query with a number of them:
https://stackoverflow.com/search?q=mutable+ivar+immutable+property
The key idea is that instance variable has a different type than the property declaration: it is mutable, whereas the property declaration is immutable.
Quick question about semantics :)
If I was writing a protocol, which is preferred:
// (a)
#protocol MyProtocol
#property (nonatomic, copy) NSSet *things;
#end
vs.
// (b)
#protocol MyProtocol
- (NSSet *)things;
- (void)setThings:(NSSet *)things;
#end
(a) is cleaner code but has the implication that implementing classes will have an ivar for things, which isn't the case in my project. Because of my use case, things cannot be KVO either. It also implies that the implementing class will copy things, which it's not doing in every case for me.
(b) is more accurate code (it's very explicit about what you can / can't do i.e. no KVO) but it's a little messier.
Any opinions?
I am amending my answer that (a) probably is not best for a protocol but best for a non-protocol interface.
I would go with the #property. How a property is implemented is an implementation detail and I never consider that from the outside.
Consider a v1 implementation where the property is only that. In v2 the internals are changed and either the setter or getter is made a method. Totally reasonable, one of the reasons that properties are good, they allow such changes, they hide the implementation details.
Also consider the opposite, in the next version where is is desired to remove the methods and replace them with a property. Again an implementation detail that a property in the first instance covers quite well.
Finally, in this case there is a copy attribute which provided explicit information of how a call with a mutable object will be handled, that is lost in the method implementation.
Protocols define messaging contracts [1]. They are not intended to store data. According to the Apple documentation you are only supposed to add properties to class extensions (you can add properties to categories but the compiler won't synthesize an ivar) [2]. Depending on what you are trying to do I would use one of the two following approaches to be consistent with the documented usage of the Objective-C language:
If you have the source code of the class (its one you created) then use a class extension.
If you do not have the source code sub-class the object.
That being said, if you really need to do it the other way use option (b). It is more corect and more correct is cleaner code!
Here is another question that deals with the same issue.
Good luck
I think case 'a' makes misinformation: class adopting protocol MyProtocol can follow not rules nonatomic and copy.
And for me it's very odd add properties inside protocols. It is going against paradigms of object oriented programming: delegates shold do some action, not provide informations.
So I advice you not use 'a' and 'b' cases, but to think again about yours programm architecture.
I have read a few questions on the differences between iVars and Properties like these: Why would you use an ivar?
ios interface iVar vs Property
What I would like to know is... If I am creating a BOOL that needs to be accessed in multiple methods in a UIViewController (for example) what is the best way to create these?
At present I create proprties. This works fine and as expected. But as I read/learn more it appears that creating an iVar would be better for performance.
Like:
#interface ViewController : UIViewController{
BOOL myBool;
}
Would this be better for performance, and can multiple methods access this iVar if I set the value to YES in one, can I check the value in the other - as I can with property approach?
can multiple methods access this iVar if I set the value to YES in one, can I check the value in the other
Of course you can, even if you set the value to NO. It is an instance variable and thus shared between all methods of one instance.
Would this be better for performance
No, unless you access the property very, very often, like 2^20 times per frame. Have a look at this Big Nerd Ranch post about iVar vs property performance. Usually the performance gain is not worth the loss in clarity.
The "better performance" is something that would be very rare to affect an app. Write code for clarity, then if there are performance issues profile and fix the code that is actually causing the problem.
For your purpose an ivar would be equivalent to using a property. Performance-wise the ivar is slightly better because you access it directly, whereas with a property you invoke a method (getter or setter) that was generated by the compiler in the background.
I wouldn't worry about performance, though. Typically the difference will be negligible. Unless you have some really special need, I would always use properties because it usually results in clearer code. It's also a good habit to have getter and setter methods - even if they are generated by the compiler for you - because they encapsulate the data of your class.
I usually go with this:
#interface MyVC : UIViewController
#property (nonatomic, getter=isDoingSomething) BOOL doingSomething;
#end
I also explicitly name the getter in the property declaration which gives you access to the property in a way that is easy to read. (Setting the property is done by sending setDoingSomething: and the getter is [theVC isDoingSomething])
Nonatomic properties are recommended on iOS. In regards to what I had backwards before, the default atomic behavior adds locks to the synthesized code, and is not recommended for performance reasons. Any issues with threads would have to be handled in your own setters (which you would have to do anyway when using an ivar). Personally I haven't ran into any issues with this.
I won't repeat other answers about performance but besides pointing out the fact that tapping a button sends way more messages than accessing a property, so the performance penalty is trivial.
So I want to have a "property" on a class but I don't want to just hold that property in memory, I want to actually store it as an NSUserDefault and retrieve it when you get that property.
So as such I have methods like this:
- (void)setUser:(User *)user {
// actually set the user as an NSUserDefault here
}
- (User *)user {
// get the user from the NSUserDefaults and return it
}
As I'm building these methods to do the work for me is there any point in having an #property declaration in the header file?
I'm getting mixed messages. Some people say that you should declare the property to force people to use the getter/setter methods, but I can't see why people wouldn't be forced to use those methods if they're all that are available?
Just looking for a bit of clarification.
Many thanks.
You should use #property because that's the modern way to define properties on Objective-C objects, even if you implement the setter and getter yourself.
Rather than relying on convention you are making your intentions much clearer to the compiler. You will also get better syntax highlighting when using dot-notation in the IDE (although that's arguably an Xcode bug).
I know that properties kind of encapsulate getter and setter methods. So whenever we say
myObject.property1 we actually cause to call [myObject property1]. From Apple documentation, Stanford iOS Courses and sample codes I can see that the usage of properties are encouraged. I aggree that using properties make a code look better and more understandable but what about performance? If I write a huge application will using properties have a noticableimpact on performance? Do professionals generally prefer direct setter and getter methods or properties?
There is no difference in performance when you use the bracket notation ([myObject property1]) or the . notation (myObject.property1).
This is more of a coding style than any thing else, so use the notation you are comfortable with or the same notation as your team if you don't work alone.
Properties are probably better because they automatically generate the methods for you and when you synthesize them you can do it like this:
#synthesize property = _property
To avoid any confusion
Also you can choose different functions/methods like:
(nonatomic, retain) // or (readonly) etc.
It also handles the memory better
Properties are definitely preferred. It is the #synthesize statement, by the way, that generate the getters and setters automatically. There are no reports known to me that would corroborate performance changes with setters / getters.
Property syntax translates directly to getter/setter calls. I have no idea which takes longer to compile, or if there is a difference, but when the program is running the code execution is the same.
When you use declared properties, the getter and setter are generated at compilation time so there is no impact on the performance whatsoever compared to declaring your getter and setter yourself.
cf. http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html