Xcode - self.viewController or _viewController [duplicate] - objective-c

This question already has answers here:
How does an underscore in front of a variable in a cocoa objective-c class work?
(9 answers)
Closed 9 years ago.
I have created a UIViewController in the .h file named myViewController.
Should I refer to it in the .m file with self.myViewController or _myViewController (being autosynthesized with that name).
Is it a personal preference or is there any difference between the two? If so, what is the difference?
Sorry for asking a strange question, but I didn't know how to google this.

Basics
Using the dot syntax is completely different from using the auto-synthesized underscore-prefixed instance variable!
When you declare a property (let's say name of type NSString *) in a class Person you get implicitly this:
#interface Person : NSObject
// #property (copy) NSString *name;
// Results in
- (NSString *)name;
- (void)setName:(NSString *)name;
#end
Plus the implementation of these methods which do nothing different than setting _name. _name is an private instance variable which is created when a property is synthesized (obviously if the property has the name viewController the name of the ivar is _viewController).
So using the “dot syntax” calls one of the two generated methods, depending on whether you assign a value or read a value.
If you want you can give the underlying ivar a different name by explicitly synthesizing the property and assigning a new name.
#implementation Person
#synthesize name = nameOfThisPerson_ivar;
...
#end
Now you won't see _name any more in the code completion but nameOfThisPerson_ivar.
Or you can implement your own name and setName: methods (or just one) but then you have to assign the value yourself (in the setter) and you have to copy it yourself, if the property's attribute is copy; if your property should be atomic, this has to be implemented by you and so on.
So what to use?
Prior to ARC you should always use the dot notation which actually calls one of the two generated methods because there the retain/release memory management was implemented for you. And I think you should still use properties because then you can e.g.
easily implement Lazy initialization
you can easily have thread safety (just by not specifying nonatomic in your properties' attributes)
and a lot of other stuff …
Edit
As Catfish_Man pointed out in the comments atomic properties do not guarantee thread safety

Related

Different Ways To Declare Objective C Instance Variables [duplicate]

I have been unable to find any information on this topic and most of what I know about it has come by complete accident (and a few hours of trying to figure out why my code wasn't working). While learning objective-c most tutorials I have found make variables and properties with the same name. I don't understand the significance because it seems that the property does all the work and the variable just kind of sits there. For instance:
Test.h
#interface Test : NSObject {
int _timesPlayed, _highscore;
}
#property int timesPlayed, highscore;
// Methods and stuff
#end
Test.m
#implementation Test
#synthesize timesPlayed = _timesPlayed;
#synthesize highscore = _highscore;
// methods and stuff
#end
What I know
1) Okay so today I found out (after hours of confusion) that no matter how much changing you do to the properties highscore = 5091231 it won't change anything when you try to call [test highscore] as it will still be returning the value of _highscore which (I think) is the ivar that was set in test.h. So all changing of variables in test.m needs to be changing _highscore and not highscore. (Correct me if I'm wrong here please)
2) If I understand it correctly (I probably don't) the ivars set in test.h represent the actual memory where as the #properties are just ways to access that memory. So outside of the implementation I can't access _highscore without going through the property.
What I don't understand
Basically what I don't get about this situation is whether or not I need to use the ivars at all or if I can just use #property and #synthesize. It seems like the ivars are just extra code that don't really do anything but confuse me. Some of the most recent tuts I've seen don't seem to use ivars but then some do. So is this just a coding preference thing or is it actually important? I have tried searching through Apple's Documentation but I get rather lost in there and never seem to find what I'm looking for. Any guidance will be greatly appreciated.
You can think of the syntax for synthesizing properties as #synthesize propertyName = variableName.
This means that if you write #synthesize highscore = _highscore; a new ivar with the name _highscore will be created for you. So if you wanted to you could access the variable that the property is stored in directly by going to the _highscore variable.
Some background
Prior to some version of the compiler that I don't remember the synthesis statement didn't create the ivar. Instead it only said what variable it should use so you had to declare both the variable and the property. If you synthesized with a underscore prefix then your variable needed to have the same prefix. Now you don't have to create the variable yourself anymore, instead a variable with the variableName that you specified in the synthesis statement will be created (if you didn't already declare it yourself in which case it is just used as the backing variable of the property).
What your code is doing
You are explicitly creating one ivar called highscore when declaring the variable and then implicitly creating another ivar called _highscore when synthesizing the property. These are not the same variable so changing one of them changes nothing about the other.
Should you use variables or not?
This is really a question about preference.
Pro variables
Some people feel that the code becomes cleaner if you don't have to write self. all over the place. People also say that it is faster since it doesn't require a method call (though it is probably never ever going to have a measurable effect on your apps performance).
Pro properties
Changing the value of the property will call all the necessary KVO methods so that other classes can get notified when the value changes. By default access to properties is also atomic (cannot be accessed from more then one thread) so the property is safer to read and write to from multiple thread (this doesn't mean that the object that the property points to is thread safe, if it's an mutable array then multiple thread can still break things really bad, it will only prevent two threads from setting the property to different things).
You can just use #property and #synthesize without declaring the ivars, as you suggested. The problem above is that your #synthesize mapped the property name to a new ivar that is generated by the compiler. So, for all intents and purposes, your class definition is now:
#interface Test : NSObject {
int timesPlayed;
int highscore;
int _timesPlayed;
int _highscore;
}
...
#end
Assigning a value directly to the ivar timesPlayed will never show up if you access it via self.timesPlayed since you didn't modify the correct ivar.
You have several choices:
1 Remove the two ivars you declared in your original post and just let the #property / #synthesize dynamic duo do their thing.
2 Change your two ivars to be prefixed by an underscore '_'
3 Change your #synthesize statements to be:
#implemenation Test
#synthesize timesPlayed;
#synthesize highscore;
...
I typically just use #property and #synthenize.
#property gives the compiler and the user directions on how to use your property. weather it has a setter, what that setter is. What type of value it expects and returns. These instructions are then used by the autocomplete (and ultimately the code that will compile against the class) and by the #synthesize
#synthesize will by default create an instance variable with the same name as your property (this can get confusing)
I typically do the following
#synthesize propertyItem = _propertyItem;
this will by default create a getter and a setter and handle the autorelease as well as create the instance variable. The instance variable it uses is _propertyItem. if you want to access the instance variable you can use it as such.
_propertyItem = #"Blah";
this is a mistake tho. You should always use the getter and setter. this will let the app release and renew as needed.
self.propertyItem = #"Blah";
This is the better way to handle it. And the reason for using the = _propertyItem section of synthesize is so you cannot do the following.
propertyItem = #"Blah"; // this will not work.
it will recommend you replace it with _propertyItem. but you should use self.propertyItem instead.
I hope that information helps.
In your example, #synthesize timesPlayed = _timesPlayed; creates a new ivar called _timesPlayed and the property refers to that ivar. timesPlayed will be an entirely separate variable with no relation whatsoever to the property. If you just use #synthesize timesPlayed; then the property will refer to timesPlayed.
The purpose of the underscore convention is to make it easier to avoid accidentally assigning directly to an ivar when you want to be doing it through the property (i.e. through the synthesized setter method). However, you can still acces _timesPlayed directly if you really want to. Synthesizing a property simply auto-generates a getter and setter for the ivar.
In general you do not need to declare an ivar for a property, although there may be special cases where you would want to.
This may be an old question.. but in "modern times", #synthesize- is NOT necessary.
#interface SomeClass : NSObject
#property NSString * autoIvar;
#end
#implementation SomeClass
- (id) init { return self = super.init ? _autoIvar = #"YAY!", self : nil; }
#end
The _underscored backing ivar IS synthesized automatically... and is available within THIS class' implementation, directly (ie. without calling self / calling the automatically generated accessors).
You only need to synthesize it if you want to support subclass' ability to access the _backingIvar (without calling self), or for myriad other reasons, described elsewhere.

What is the difference between these three ways to declare a variable?

I am learning Objective-C and was just curious. I can create an object of a NSString in these places, and please provide any others. To me they all do the same thing. I don't know what is the difference is between them. Where is it stored? From where can I access it? What are the advantages?
1)
// .h
#interface ...
#property (strong,nonatomic) NSString *text;
#end
2)
// .h
#interface ... {
NSString *text
}
#end
3)
// .m
#interface ... ()
#property (strong,nonatomic) NSString *text;
#end
First and foremost, my answer is based on the latest Clang compiler, older versions worked slightly different.
So, you're not creating an object in neither. You're not even declaring an object in two of them.
In the first case, you're actually telling the compiler that you need to expose a property called text of type NSString. What the compiler does, is declaring an instance variable for you _text (which you can access without a problem by the way) and the methods needed to get and set that instance variable. As you can see the storage is still internal, you just have getters and setters set for you.
In the second case you're actually declaring an instance variable (ivar) yourself, just as the compiler does with _text. It's accustom to prefix it with _. The storage is still internal. On top of that, you can't access your ivar from outside, since it has no getter or setter and the implicit declaration is #private.
In the third case, you create an anonymous category (thus the empty parentheses) which adds a property to your class. Storage for this is a little bit harder/longer to explain, if you are curious about it, you can search up the Apple docs, see what a category is and so on. You can only access your property from within your class in this case, which makes it somehow redundant (the getters and setters), you could have declared it as an ivar.
You can also declare your ivars like this:
#interface GenericViewController : UIViewController{
NSString * text;
}
#end
#implementation GenericViewController{
NSString * text;
}
#end
Both of the above have local storage and private visibility (can't be accessed from outside). The difference between the two is that instance variables declared in the implementation are implicitly hidden and the visibility cannot be changed with #public, #protected and #private. If you use those directives you won't get compiler errors but are ignored.

#synthesize ivarName = _ivarName convention, preference or performance? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Synthesized property and variable with underscore prefix: what does this mean?
The usage of Objective-C properties has always felt awkward to me. It's one of the "I know how to use them, but I'm not always sure why I'm using them." kind of things and recently I've been seeing a lot of this:
// in .h file
#interface MyObject : NSObject
{
id _coolIvar;
}
#property (assign) id coolIvar;
#end
// in .m file
#implementation
#synthesize coolIvar = _coolIvar;// <- whats the point of that.
#end
So what is the point of declaring an ivar with an underscore and then using #synthesize to access it, Opposed to just declaring the #property with the same name as the ivar?
Side Question:
I've noticed that this convention has been becoming increasingly more popular since blocks started becoming the preferred approach for async callbacks opposed to the target/selector approach. Is that a coincidence or does the above #property declaration convention play nicer with block scopes?
It's preference.
It's also my preference to not declare the variables twice and just let them be synthesized like:
// in .h file
#interface MyObject : NSObject
#property (assign) id coolIvar;
#end
// in .m file
#implementation
#synthesize coolIvar = _coolIvar;
#end
The two reasons I like to use the _ prefix is
I know when I am going through an accessor and when I am accessing the variable straight.
If it makes sense for me to call an ivar address it is more than likely that inside a method a similar variable would also be logically called address. If my ivar does not have an _ prefix then my local address will mask the ivar address.
I also like how xcode will autocomplete vaiables starting with an _ when you start typing your #synthesize myVar = _...
NB
You may run into the odd name clash (I have only once) but the warning that the complier gives you makes it a pretty easy spot and simply changing the name is a quick win.
#isaac touched on not declaring ivars so that they are not publicly advertised but does not explain how/why. Basically you can declare #property's in a class extension to still give you the benefits of the #synthesized getter/setter but without making your public API look ugly.
Your previous example would look like this (if you wanted coolIvar to not be publicaly advertised):
// in .h file
#interface MyObject : NSObject
#end
// in .m file
#interface MyObject () <-- Like a category but with no name
#property (assign) id coolIvar;
#end
#implementation
#synthesize coolIvar = _coolIvar;
#end
I use the _ivar construct to make sure that I don't access the ivar directly (by mistake) when I really intend to go through the accessors.
With the modern runtime (iPhone applications and 64-bit programs on Mac OS X v10.5 and later) the ivar declaration is no longer required. So your code is reduced to:
// in .h file
#interface MyObject : NSObject
#property (assign) id coolIvar;
#end
// in .m file
#implementation
#synthesize coolIvar = _coolIvar;
#end
Per #Monolo's answer, the _ivar is a good failsafe to make sure you don't inadvertently access the ivar directly. Remember, the #property and #synthesize is there to replace boilerplate code - without it you'd have to code getter and setter accessors.
There are a couple benefits to differentiating ivars from property accessors.
One is described by Monolo - it prevents mistakingly accessing an ivar when what you intended to access was a property.
Another is that in theory it guards against collisions - cases where you might name an ivar identically to another ivar that's beyond your implementation (ie, a superclass ivar name).
There are different thoughts on best practices, but lately I've read in several places I consider reliable that the best practice is actually to no longer to declare ivars at all in your interfaces (ivars are created implicitly via the property declaration).
Some people don't like "implicit" - but there are material benefits: Not declaring them avoids advertising ivars that aren't really public. It also goes even further in avoiding collisions - because in theory when a property is synthesized and the ivar generated, it will do so without introducing a convention that may itself collide with a private ivar naming convention (as may be the case with preceding or trailing underscore).
Preference. Some people like to prefix instance variables with a underscore (so one can easily tell if one is referencing a ivar, or a variable in a more local scope), and some don't.

Objective-C: Xcode automatically recognizes ' = _property ": is this #synthesize created variable name?

When you declare a #property and #synthesize it, it is considered good practice to use:
#synthesize myProperty = _myProperty;
I've noticed that Xcode will autocomplete the ivar name _myProperty for you, even though it hasn't yet been used in the source code.
Is this because the ivar #synthesize creates automatically defaults to the name _myProperty? Or merely because Xcode supports this common convention with an autocompletion for it?
Thanks.
EDIT: I'm not looking for reasons why this is good practice; I'm already aware of those and have used this convention for a while. I want to understand the internals, thus am asking whether this is a hard-coded auto-completion rule to satisfy a convention, or whether it's standard auto-completion and in fact the Objective-C specification dictates that an ivar generated by #synthesize must have the form _myProperty, thus after behind the scenes generation of the ivar, auto-completion is aware of its existence. Thanks!
I think the autocompletion is an IDE convenience rather than a result of the runtime. My logic for this is that the following appears to be valid:
#interface SomeClass()
#property (nonatomic, assign) int unpublishedInstanceVariable;
#end
#implementation SomeClass
#synthesize unpublishedInstanceVariable;
- (void)someMethod
{
unpublishedInstanceVariable = 3; // not calling the setter
}
#end
hard-coded auto-completion rule to satisfy the convention
If you don't specify an iVar name explicitly, it will be called myProperty. The autocomplete doesn't have anything to do with the compiler, it's just Xcode being extra helpful.
As of Xcode 4.4, there is a new twist to the tail (sic).
We are now allowed to skip the #synthesize altogether. In this case, the compiler automatically generates the #synthesize foo = _foo; declaration for us, with the instance variable name prefixed with an underscore.
#interface Foo : NSObject
#property (nonatomic, copy) NSString *foo;
#end
#implementation Foo
- (void)bar {
NSLog(#"%#", _foo); // this Works!
}
#end
However, if we do have an explicit #synthesize statement but do not specify the name of the instance variable, then the default name of the instance variable is the same as that of the property i.e. not prefixed with an underscore, in which case #Tommy's answer still holds.
It'd be great if someone could point out the links to official Apple Docs that document this behaviour.
Update
My findings were spot on. This behaviour (of #synthesize being the default, and creating a backing underscore prefixed instance variable in the absence of an explicit synthesize etc.) was publicly announced in WWDC 2012 Session 405 - Modern Objective-C.
wrt this part of your question:
whether ... in fact the Objective-C
specification dictates that an ivar generated by #synthesize must have
the form _myProperty,
You can name your ivar anything you want. From the docs:
You can use the form property=ivar to indicate that a particular
instance variable should be used for the property, for example:
#synthesize firstName, lastName, age=yearsOld;
This specifies that the accessor methods for firstName, lastName, and age should be
synthesized and that the property age is represented by the instance
variable yearsOld.
Also,
The #synthesize directive also synthesizes an appropriate instance variable if it is not otherwise declared.

public objects and use of property

I'm a bit confused; if an object is declared in the .h file it is considered automatically as "public" right? We use a #property in the .h file, however, to edit them? This is where I don't understand: we use the getter/setter for private objects, so why do we use the #property for objects declared in the .h file and thus considered as "public"?
Second thing, I found this example: I don't understand why we use a #synthesize for primaryKey in this code: http://staging.icodeblog.com/wp-content/uploads/2008/08/9-todom1.png
and why we don't use a #property for the database object?
It is not correct that if an object (ivar) is declared in a .h file, then it is public. It is only if getter/setter methods are provided, otherwise it is not.
Indeed, the #property/#synthesize directives are facilities meant to declare and define default getter/setter methods. So, instead of writing them yourself, you just use the directives.
It is also worth noting that declaring properties you get the possibility of using the dot notation to refer properties of your objects. And also that they clarify a lot, thanks to the retain/assign/copy specifiers, how memory is meant to be managed for that properties. (And, of course, #synthesize will just do that correctly for you).
About your sample, in fact, whether an ivar is associated to a property or not is a design choice. Possibly, you just reconsider the assumption that ivars declared in .h files are public by defaults, and it will become clearer. In other words: primaryKey is public, database is not.
A very nice tutorial can be found here but also do not forget Apple docs.
EDIT:
about your question from the comment section:
it is not necessary that every ivar has a property, nor that it has getter/setter in order to be used inside of that class implementation.
#interface SomeClass : NSObject {
AnotherClass* _anotherClassObj;
AThirdClass* _aThirdClassObj;
}
#property (nonatomic, retain) AnotherClass* anotherClassObj;
#end
So, here you have two ivars; only one has got a #property declaration. In your .m file you may have, e.g.
#implementation SomeClass;
#synthesize anotherClassObj = _anotherClassObj;
- (void)initWithClasses:(AnotherClass*)obj1 and:(AThirdClass*)obj2 {
.....
self.anotherClassObj = obj1;
_aThirdClassObj = obj2;
...
}
....
#end
In this code:
#synthesize will provide implementation for getter/setter for anotherClassObj so you can use syntax: self.anotherClassObj = obj1; that syntax can be used equally from inside and outside the class implementation;
when you have no getter/setter (either auto-generated or custom) you can assign directly to an ivar by using the syntax _aThirdClassObj = obj2;, with the semantics of simple pointer copy; anyway, _aThirdClassObj will not accessible from outside that class;
furthermore, #property ... anotherClassObj notwithstanding, you can still refer _anotherClassObj directly in your .m file, like in _anotherClassObj = xxx, bypassing getter/setter, if you ever need it.
One thing you should have clear is that getter/setter are not only a way to make an ivar "public". They also play an important role in managing the retain count (depending on which specifier you choose among retain/assign/copy in the property declaration). So, in self.anotherClassObj = obj1; above, obj1 is assigned to _anotherClassObj and it is also retained (and if _anotherClassObj was previously pointing to an object, that object will be sent a release). Raw ivar assignment does not provide that kind of facility.
In my opinion, the retain count management feature of properties is far more important than visibility for deciding whether I use a property or not.
Not everything in the header is public, by default ivars (items in the { }) are #protected. The purpose of the #property is data encapsulation. #synthesize or #dynamic is used for declaring the way you want to implement your property and one or the other is necessary to prevent crashes and warnings.
Resources:
Defining Classes #protected, #package, #private, #public reference
Declared Properties #property reference