After reading about properties and ivars in Objective C I'm still confused with MasterDetail template for iOS in XCode.
MasterViewController declares property for DetailViewController:
#class DetailViewController;
#interface MasterViewController : UITableViewController
#property (strong, nonatomic) DetailViewController *detailViewController;
#end
And ivar for array of objects:
#interface MasterViewController () {
NSMutableArray *_objects;
}
#end
Why is it that way? I just can't get why those two things are declared differently.
Thanks.
Declaring something as a "property" allows other objects to access and work with it. In The case above, adding "detailViewController" as a property to MasterViewController means other objects can access and work with the methods & properties DetailViewController exposes.
While the "_objects" variable is internal (or private) to the MasterViewController.
Apple's documentation is generally excellent. Apple's templates are... sometimes a little challenged. They are also sometimes slow to be updated as the language improves (or they are updated erratically). The objects array should really be a private property rather than an implementation-declared ivar. In any case, don't read too much into this.
Remember, the view controller shouldn't even be holding the data; it should be getting it from the model classes (which the template doesn't provide). Some of this is in order to keep the templates simpler to use (they're not actually example code; they're templates). Some of the weird code is due to limitations in the templating engine. (They didn't used to be able to prefix your classnames, even though they told you that you must prefix your classnames; it was very annoying.)
Unfortunately, seeing something in example code also doesn't necessarily mean it's a correct way to code. Much of Apple's example code would be completely inappropriate in production code (most of their examples lack proper model classes, or fail to handle errors correctly). But again, that's kind of the nature of example code. Focus on the coding guidelines. They're much more useful than learning from templates and examples.
Related
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.
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.
approach 1:
#interface MyController : UIViewController {
UILabel *myText;
}
#property (nonatomic, strong) UILabel *myText;
approach 2:
#interface MyController : UIViewController
#property (nonatomic, strong) UILabel *myText;
approach 3:
#interface MyController : UIViewController {
UILabel *myText;
}
I have read some articles talking about this kind of stuff but I still do not really realize which approach I have to adopt.
I also found that someone said approach 1 is a old way so I would like to know the best practice for ios sdk 6 using ARC.
I know that declaring variables using property is a easy way for generating getter and setter and someone suggested using it. However, I would like to ask in case a variable is not for calling by another class, is it necessary for the variable using property? and set it as private variable inside the interface? Or is it better for a variable only declaring inside the interface? I would like to learn the best practice so please forgive me if this is a silly question.
Moreover, some developers write #synthesize in this way
#synthesize myText=_myText;
but some write this:
#synthesize myText;
I would also want to know the difference and which one is preferable?
Thank you very much!
The most modern way1:
whenever possible, declare properties
don't declare iVars separately 2
don't #synthesize 3
locate as few properties as possible in you .h file 4
locate as many properties as possible in a class extension in your .m file 5
1 As of Xcode 4.5.2. Most of this applies back to 4.4, some of it won't compile on 4.2 (the last version available under Snow Leopard). This is preprocessor stuff, so it is all compatible back at least to iOS5 (I haven't tested on iOS4 but that should also be OK).
2 There is no point in declaring an iVar as well as a property. I am sure there are a few obscure cases where you would want to declare iVars instead of properties but I can't think of any.
3 Xcode will create an iVar with the same name as the property, preceded by an _underscore. If you (rarely) need some other kind of behaviour, you can manually #synthesize property = someOtherName. #vikingosegundo links us to this article on dynamic ivars, which is a use case for #synthesize. #RobNapier comments that you do need to #synthesize iVar = _iVar (bizarrely) if you are creating your own getters (readonly) and setters (read/write) for a property, as in this case the preprocessor will not generate the iVar for you.
4 The general rule with your interface: keep it as empty as possible. You don't actually need to declare your methods now at all, if they are for private use. If you can get the code to work without an interface declaration, that's the way to go.
5 This is an #interface block in your .m file, placed above your #implementation:
#TestClass.m
#interface TestClass()
//private property declarations here
#end
#implementation TestClass
...
You may also want to use #synthesize if you like a nice table of contents of your #synthesized properties that you can refer to and comment for clarity and organization.
Also, an #synthesize allows you to set a breakpoint on the property and trap when its value is changed.
When the compiler does everything for you, you end up being distanced from what is really happening and ignorant to it. However, not having to type out everything yourself all the time is also nice.
Not a complete noob I am quite new to iOS programming and to Ojbective-C. I mainly come from a background of C (DSP, Microcontrollers), Delphi XE2/Pascal , Visual Basic and Java (desktop and Android apps).
I mainly learned Cocoa with the book "Beginning iOS 5 Development", from Apress.
Recently I watched videos of the WWDC 2012 and went through some of their sample code, and I must say that I am confused of what is the proper way of writing my apps and more specifically with the #property/#synthesize words.
In the book most (not to say all) of the sample code uses to define a property as for example
ViewController.h
#property (strong, nonatomic) NSMutableArray *list;
ViewController.m
#synthesize list;
then all the code access synthesize list with
self.list
or even simply
list
Now in every WWDC code sample I read I see that programmers define a property but then, in the .m file they do things like
#synthesize list = _list;
and access sometimes
self.list
or
_list
I am confused. What is the correct practice ? As Apple programmers all use underscore I think I should do it that way but why the book did not ? Is there a difference between list and _list ? And more over, as I am in the same object why sometime use self.list and sometimes list/_list.
Sometimes they don't use #synthesize, I assume it's when they want to re-write their own accessors and mutators (which is never my case up to now).
I have read here and there on the web but nothing was clear enough to set my mind right, so I count on StackOverflow to bring light here.
Last but not least I prefer and answer based on current iOS 6 best practice/programming technique. Useless to tell me how to do it correctly in older iOS.
There is no correct way. There is only your preferred style.
The lastest compilers do an implicit synthesise on the property declaration.
#synthesize list = _list; .
Nothing is ever written in your code. It just happens.
However that doesnt stop you doing this explicitly.
#synthesize list = somethingelse;
So when you ask for a pointer to list via the accessor (self.list) you will get a pointer to somethingelse
In most cases NSMutableArray *thing = self.list is equivalent to NSMutableArray *thing = somethingelse
And just because Apple uses a style doesn't mean that you have to do it. Each company usually has their own coding style.
The main problem with using #synthesize list; is that it poses the risk that you can write either
self.list = thing or list = thing .
The former uses the sythesised setList: accessor while the latter doesn't and put the risk of related bugs in your code , though its not as bad with ARC as you dont get leaks happening for strong properties.
What ever style you use, keep it consistent and be aware of the effects of using an ivar directly list = thing as compared to using its accessor self.list = thing
This is a language feature that has had its usage evolve rapidly over the past few years, which explains the various forms. With the most recent tools, you can choose to ignore #synthesize and have things work reasonably.
The default behavior in that case produces the same effect as #synthesize list = _list;.