concepts of properties with corresponding ivars - iphone

i have a general question about properties and ivars.
ive seen many different examples to use properties and it confuses me a bit.
method 1 only using a property without a corresponding ivar.
#property (...) Type *name;
#synthesize name;
method 2 using a property and an ivar
#interface{
Type *ivarName;
}
#property (...) Type *name;
#synthesize name = ivarName;
method 3 ignoring properties and working with ivars
#interface{
Type *ivarName;
}
ivar = ...;
i currently use method 1 for most things i do, it just works. but i have startet to wonder if i might be missing something here. i have read a lot of questions about ivars VS properties, but none of them seemed to really care about how they work together.
in most sample projects i've seen method 2 is used. so my question is: is there any advantage in defining a property and an ivar, and then assign the property to the ivar, than just having a property?
is the solution as simple as: only with a property can an ivar be set from 'outside'?
i have read: Must every ivar be a property? and Property vs. ivar in times of ARC but was not able to draw a final conclusion.

is the solution as simple as: only with a property can an ivar be set from 'outside'?
Essentially, yes. Ivars in Obj-C are (by default) "protected", meaning that the compiler won't allow you to access them externally to the object's own code. For example, given the following class declaration:
#interface Dunstable : NSObject
{
NSString * crunk;
}
#end
You might think you'd be able to access the ivar after creating the object, but trying results in an error:
Dunstable * d = [[Dunstable alloc] init];
d->crunk = #"Forsooth"; // Error: "Instance variable 'crunk' is protected
That's why ObjC uses accessor methods. Defining them manually was mandatory before the advent of declared properties:
#implementation Dunstable
- (NSString *)crunk {
return crunk; // implicit ivar access, i.e. self->crunk
}
- (void)setCrunk: (NSString *)newCrunk {
[newCrunk retain];
[crunk release];
crunk = newCrunk;
}
#end
Now, using the #property and #synthesize directives creates those accessor methods for you (as well as the variable itself). (The manual memory management in the setter is of course also obsolete under ARC.)
It is possible to make an ivar that's accessible from outside the object:
#interface Dunstable : NSObject
{
#public
NSNumber * nonce;
}
#end
Dunstable * d = [[Dunstable alloc] init];
d->nonce = [NSNumber numberWithInt:2]; // Works fine
but this isn't considered good Objective-C style.
The Objective-C Programming Language doc contains a "Historical Note" about this:
Note: Historically, the interface required declarations of a class’s instance variables, the data structures that are part of each instance of the class. These were declared in braces after the #interface declaration and before method declarations:
[...]
Instance variables represent an implementation detail, and should typically not be accessed outside of the class itself. Moreover, you can declare them in the implementation block or synthesize them using declared properties. Typically you should not, therefore, declare instance variables in the public interface and so you should omit the braces.
This is a pretty big change (I was actually surprised that there's no syntax given for ivars declared in #interface anymore in that doc), but it's definitely for the better. You should use declared properties; they do the right thing and make your code cleaner and safer.

When you write:
#synthesize name;
an ivar name is created, and it has the same name as the property. So you can access it with or without self.
In reality if you write
self.name = #"hello";
you are accessing the property, and if you write
name = #"hello";
you are accessing the ivar. Most people (including me) will advise you not to access your ivars directly unless it is really what you want: for example, if you are creating a custom setter or getter for the property. Otherwise always access the property with self.
In my case I always do:
#synthesize name = _name;
The advantage of this approach is that when you forget to write self instead of accessing the ivar you will get an error telling you that the ivar name doesn't exist.

You should never access ivars directly from outside of a class. That's the main function of properties--defining accessor methods for use by other objects. However, it's also good practice to use your accessors from within the same class--this way you can ensure that any appropriate side effects take place (memory management is an obvious example, if you aren't using ARC).
So, Method 3 is usually wrong. Method 1 is roughly equivalent to Method 2--that is, behind the scenes, the runtime is basically creating an ivar for you. Note also that you can set the name of that ivar even if you didn't explicitly define it:
#interface{
//No ivar here!
}
#property (...) Type *name;
#synthesize name = ivarName;

From the second link you supplied, Property vs. ivar in times of ARC, the comment by Denis Mikhaylov on the accepted answer is very telling. He points out that with your case 3, that you can access the iVar through:
classInstance->iVar = #"New value"
But this is considered bad practice. So i'd restate your point as:
Only with a property should an ivar be set from 'outside'

Related

#class #synthesize useablility

Ok, I have class, that I create for my Core Data
LoginPass.h
Then I have First class
FirstClass.h
And then I need use this classes in SecondClass, where I declare them with #class. Heder file
SecondClass.h
...
#class FirstClass;
#class LoginPass;
...
#interface SecondClass : UIViewController
{
......
}
#property (strong, nonatomic) FirstClass *fromFirstClass;
#property (strong, nonatomic) LoginPass *myEntity;
...
#end
And in .m file
#import "SecondClass.h"
#import "FirstClass.h"
#import "LoginPass.h"
#implementation SecondClass
...
#synthesize fromFirstClass = _fromFirstClass;
#synthesize myEntity = _myEntity;
...
Ok, I can make some mistakes in code, sry for it.
I really don't know and now don't interesting why I need write
#synthesize myEntity = _myEntity;
but not
#synthesize myEntity;
But I have another question. Why I can use then in my code
self.fromFirstClass
But I cann't use
self.myEntity
Xcode give me an error and say me that I should use
self._myEntity
What the difference? Why I can use self.fromFirstClass but not self.myEntity?
#end
You are confusing instance variables which are variables parts of an object structure, and properties which are really methods to set and get a value.
When you declare #property (strong, nonatomic) FirstClass *fromFirstClass; you actually declare two methods - (FirstClass *)fromFirstClass and - (void)setFromFirstClass:(FirstClass *)aFirstClass.
When you use the dot syntax FirstClass *classA = self.fromFirstClass;, you actually call a method, it is equivalent to FirstClass *classA = [self fromFirstClass];. In the same way, if you write self.fromFirstClass = classB;, you actually call: [self setFromFirstClass:classB];.
If you use the name of an instance variable directly inside an object method, you access this variable.
Now, when you write #synthesize fromFirstClass; in the modern runtime, you let the compiler create a instance variable with the same name fromFirstClass and write the two methods - (FirstClass *)fromFirstClass and - (void)setFromFirstClass:(FirstClass *)aFirstClass that will get and set the instance variable.
If you write #synthesize fromFirstClass = _fromFirstClass;, the same thing happens, except the name of the instance variable which is created has an underscore in front of it.
Finally, in the more recent versions of the compiler, if you don't write anything, the default behavior is to #synthesize fromFirstClass = _fromFirstClass automatically for you.
#synthesize fromFirstClass = _fromFirstClass;
#synthesize myEntity = _myEntity;
These above lines are correct but nowadays you are not required to synthesize.#synthesize is put by compiler itself.
When you use self.prop you mean you are accessing property.
When you use _prop you call property directly.
EDIT:
When you use self.prop you call the method depending on lhs or rhs of =(assignment) :
-(NSString *)prop; //gets called when you use myName=self.prop;
and/or
-(void)setProp; //gets called when you use self.prop=#"master";
On the other side, if you try to use self._myEntity then it will look for method name having _ which is not there, resulting in Error.
The compiler would add
#synthesize myEntity = _myEntity;
if you omit the #synthesize totally.
However, you could use as well
#synthesize myEntity;
The key difference is that in the first case, your local variable is called _myEntity while the getter is myEntity and the setter is setMyEntity. So from external you would access yourObject.myEntity either for setting or getting the value. The compiler will take care, that the setter and getter is called. You do not access the prperty directly.
[yourObject.myEntity = value] ist identical to [yourObject setMyEntity:value] as well as value = yourObject.myEntity is identical to value = [yourObject myEntity].
So far from accessing properties or their getter and setter from outside. From inside your class you may think that self.myEntity = value is identical to myEntity = value (for the second case). But it is NOT. self.myEntity calls the setter (or getter). This is important especially for the getter becaus that comes with important memory management for free - with or without ARC. While myEntity = value directly accesses the property.
And here comes the _ and its key advantage (imho). If you use the _ notation then the property is called _myValue. Doing so it is explicitely clear for you and the readers of your code when the actual property is accessed directly and when the getter and setter are used.

Objective-C: _variable

OK, this must have been asked before but I looked like mad and found nothing:
I have a simple array in my iphone app which I define like so:
#property (nonatomic, strong) NSArray *pages;
#synthesize pages = _pages;
I've seen this in Apples sample code and thought this is a nice short-cut for writing self.pages (i.e. _pages replaces self.pages) like so:
_pages = [[NSArray alloc] init];
but then Apple has this again (not exactly like this, but it appears as if they keep swapping randomly):
self.pages = [NSKeyedUnarchiver unarchiveObjectWithData:contents];
And finally:
[_pages release];
Which totally confuses me. What would be the difference between _pages and self.pages?
Thanks for your help.
_pages is the name of the object's ivar. pages is the property name which is different.
So, #synthesize pages = _pages; finally tells that pages is the property for the ivar _pages.
You will encouter the ivar direct access via _pages in initializers and dealloc methods. Every where else, the property name is used to get/set its value.
When you use a simple assignation :
_pages = ...
you simply set the instance variable.
When you use a property assignation :
self.pages = ...
It call a method synthesized automatically by the compiler (or defined by you) and for synthesizing this method, it checks the type of the property (retain, assign, ...) and writes code to match this type of property.
This difference comes from common naming and usage practices.
Both the instance variable and the property refer to the same object. The difference in naming is used for pointing out the difference between the ivar (_pages) and the property (pages).
The ivar is owned by the instances of the class and it's up to them to handle ownership operations for it (alloc, retain, release, etc.). Typically, these ownership operations take place in init and dealloc.
On the other hand, the property provides the 'designated' access point for the ivar. The property methods (the setter and getter) may perform additional operations required for the proper management of the ivar. So accessing the ivar directly (as a usage pattern) is not recommended, even within the owning objects. For example, a setter might be implemented like this:
- (void) setPages:(NSArray *)newValue {
[newValue retain];
// additional operations that you will miss if you use the ivar
[someObject someUsefulOperationThatIsReallyNeeded];
[pages release];
_pages = newValue;
}
_pages is the instance variable and pages is the property name. The property is accessed via the getter and setter methods pages and setPages: object.pages is equivalent to [object pages] or for your example `[self setPages:[NSKeyedUnarchiver unarchiveObjectWithData:contents]];
So the only actual object is the instance variable _pages and so only this can be memory managed.
The property and synthesiser code in effect give the same as this code (in practice there could be extra code for memory management and thread locking
#interface MyClass
{
...
NSArray *_pages
}
- (NSArray*)pages;
- (void)setPages:(NSArray*)newValue;
#end
#implementation MyClass
- (NSArray*)pages
{
return _pages;
}
- (void)setPages:(NSArray*)newValue
{
_pages = newValue; // Note in non ARC code there would be some memort managment here
}
#end
You can reference an #synthesized property either as instanceVariableName or as self.propertyName. The two names can be the same or different.
When you reference as instanceVariableName, and modify the value, none of the retain/copy logic of the associated property is applied -- you're just referencing the "raw" variable. When you reference self.propertyName, the retain/copy logic is applied, and, eg, if the property is declared with "retain" then the old value will be released and the new value retained.
When assigning an already-retained value (such as one from alloc/init) to a property, it's simpler (if this an initialization where the property was previously nil) to assign to instanceVariableName and skip the need to release the value (so that the net number of retains will be 1 at the end of the operation). But when assigning a value that is not retained (other than an autoreleased retain) to a property, you want to have the property's retain occur, so you'd use the self.propertyName notation.
Using a leading "_" for an instance variable that is also a property is a simple convention to keep these two apart, and avoid accidentally referencing one (by adding/removing self erroneously) when you meant the other.

difference between object.variable and object->variable

What is the difference in using object.variable and object->variable? When should I use object->variable?
As Objective C is a superset of C when using '->' syntax (which is similar to (*obj).var) you are accessing the instance variable (ivar) like in C-structure (well, classes in ObjC are just fancy C-structures).
Thus using the '.' implies that you're accessing the property. Properties is the feature that was added in Objective C 2.0 and allows you access your ivars via setter/getter methods, that could be created automatically (using #synthesize) or you can provide your own implementation. BTW it is absolutely not necessary for properties to have corresponding ivar. For example in #interface you declare:
#interface Ololo : NSObject {
//NOTE: there is no ivar named someText or _someText or whatever you want
}
#property(nonatomic) NSString* someText;
#end
Then in #implementation:
#implementation Ololo
#dynamic someText; //we're using this to tell compiler that we will provide getters/setters ourselves and it doesn't need to generate them (though it is not necessary to do that)
-(NSString*) someText {
return [NSString stringWithContentsOfFile: #"some_file_path"]; //we actually get value from file
}
-(void) setSomeText:(NSString*) str {
[#"asdas" writeToFile: #"some_file_path" atomically: YES];
}
#end
Actually you can do whatever you want in those methods. So using '.' is just shortcut for [obj setSomeText: #"hello"].
If you use . you are accessing a property of the class which you defined using #property and created with #synthesize. If you use -> you just access an instance variable, but its not really something you should use a lot. And the use is very limited. So don't make it difficult for yourself and use properties with .
The indirection operator (->) is inherited from C and can be used as a shorthand for accessing fields in a structure, to which you have a pointer.
As an example...
typedef struct IPhone {
int serialId;
} IPhone;
Here I have a traditional C struct which I can instantiate as follows...
IPhone *phone = (IPhone*)malloc(sizeof(IPhone));
Now to access its fields I can either do it the long way...
*(phone).serialId = 1123432324;
Or I can use the shorthand indirection operator...
phone->serialiId = 1123432324;
At the heart of every ObjectiveC class is a C struct. So what you're doing when you use the indirection operator is to jump back to old C syntax to backdoor into the underlying representation. It works, but it's not the prescribed ObjectiveC way.
object->variable is direct access to the variable. object.variable is a method call to the getter accessor method '-(id)variable'or setter accessor method '-(void)setVariable:(id)value' depending on context. You must write the accessor methods yourself or use #synthesize to generate them in order to use dot syntax.
Good programming practice dictates you always use accessor methods to access an instance variable from another instance. ie, dont use ->

Difference between class property mVar and instance variable self.mVar

I am some what confused as to the difference between accessing an instance variable via self or just by name (when working inside the class).
For instance, take this class:
//In .h file:
#interface Register : NSObject {
NSString *mName;
}
- (id) initWithName:(NSString *) name;
//In .m file:
- (id) initWithName:(NSString *)name
{
if (self == [super init])
{
mName = name;
}
return self;
}
What's the difference between accessing the instance variable via
self.mName = name;
vs
mName = name;
Which isn't a #property and is not #sythenize'd.
Say it is this though, per this example:
//In .h file:
#interface Manange_My_ViewsViewController : UIViewController {
IBOutlet UILabel *countLabel;
}
#property (nonatomic, retain) IBOutlet UILabel *countLabel;
//In .m file:
#synthesize countLabel;
- (void) updateLabel:(NSUInteger)count
{
countLabel.text = [NSString stringWithFormat:#"%d", count];
}
But say I accessed countLabel as:
self.countLabel
What would be the difference?
Edit: Third example per users' answer:
Say it the iVar wasn't an IBOutlet:
//In .h file:
#interface Fake : NSObject {
NSString *mVar;
}
#property (nonatomic, retain) NSString *mVar;
//In .m file:
#synthesize mVar;
mVar = #"";
VS
self.mVar = #"";
Or is it the same - that in the first we are accessing the actual instance variable and in the second we're actually going through the auto created setter (via #synthesize)?
Thanks all!
Edit: Update in response to Peter Hosey ...
So your thinking the convention of mVarName is bad? I took that from my C++ days.
But what about the case when you do?
-(void) someMethod:(int) x
{
x = x;
}
You can't do that (Say 'x' is also a class variable)
But you can do:
-(void) someMethod:(int) x
{
mX = x;
}
But your saying its better to do:
-(void) someMethod:(int) x
{
self.x = x;
}
What's the difference between accessing the instance variable via
self.mName = name;
vs
mName = name;
The first is property access syntax. It translates to an accessor message to the object (in this case, self). That is, that statement implicitly translates to this message expression statement:
[self setMName:name];
(Awkward accessor names like that are why “mName” is a poor name for a property. There is property declaration syntax to work around that, letting you name the property “name” and your instance variable “mName” and map one to the other.)
The second example directly accesses the instance variable—no accessor message.
Which isn't a #property and is not #sythenize'd.
Say it is this though, …
If no property named “mName” is declared for a class, then you can't use property access syntax to access a property by that name on an instance of that class.
And it doesn't matter whether you synthesize the accessors, hand-wave them to a superclass with #dynamic, or define them yourself. That's how the object will respond to the accessor message, but the accessor message the compiler generates will be no different (since a property access could just as easily come from outside the class as from inside it).
Say it the iVar wasn't an IBOutlet:
That doesn't matter. IBOutlet only means anything to IB. Everything else doesn't care.
In fact, IBOutlet is currently just a macro that expands to nothing. After your code gets preprocessed, the word “IBOutlet” is no longer there, so the compiler never sees it. That's how little a difference it makes to anything but IB: None at all.
Edit in response to question edit
I said mName is bad as a property name, because of the accessor names that follow from it. The name of an instance variable is a separate issue, particularly since the property and ivar don't have to have the same name.
For a variable, be it an instance variable or a local variable, the choice of name or m_name or mName is purely a style choice.
someMethod: is generally the accessor, setX:. Within that method, self.x = x, which is [self setX:x], causes infinite recursion. So don't do that.
When someMethod: isn't the accessor (or init or dealloc), using the property is just fine and generally preferable. However, in that case, you're not likely to give one of its arguments the same name as an instance variable. When such a case could occur, name the local variable more specifically, because its purpose is more specific. This, too, is a style issue.
When it is the accessor, I name the local variable newX, having named the instance variable the same as the property, x. This is my own personal style; as I said, naming the property x, the ivar mX, and the local variable x is fine too (aside from the excessive brevity of this example).
OK, first off is the basic difference:
mVar = var;
This is just changing a value. That's it.
self.mVar = var;
This is equivalent to:
[self setMVar:var];
In other words, one invokes a method, the other does not. Using the #property syntax can give you some really neat benefits. For example, you get key-value coding compliance for free. That means that another object can observe this object's mVar property, and be automatically notified whenever it changes, without you doing anything. You don't get this if you just access the ivar directly. (Unless, of course, you implement it yourself. But why would you do that?)
You also get semi-free memory management. If you declare a property as (retain), then you don't have to [newValue retain] yourself. The synthesized method will do this for you (in both cases, you'd still have to [ivar release] in your dealloc method).
You also can get some degree of thread safety. If you don't declare a property as (nonatomic), then it is (by default) atomic (although that keyword does not exist; it's implied). That means that reading/updating the value of the property is an atomic operation. If you were to just access the ivar directly, you'd have to implement the atomicity yourself with a lock.
Basically, using the synthesized methods gets you some really neat stuff for free. The only reason I'd say to not use the #property syntax is if you have irrefutable evidence that invoking those methods is a bottleneck in your code. However, you'll be really hard pressed to come up with a situation where that would be the case.
First of all, with a read-only property--which an IBOutlet essentially is--it does not matter as much.
The key difference is that the property is actually calling the accessor method while the instance variable is being accessed directly.
Thus, for setting a retain property, using self and the accessor will release the old object and retain the new one. Setting the instance variable directly will NOT impact the retain counts of any objects.
Using #synthesize will generate standard accessors for you.
The key reason to use properties is that, since they are accessors, they can be read and/or modified from outside the class.

iPhone ivar naming convention [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How does an underscore in front of a variable in a cocoa objective-c class work?
I've noticed that in a lot of the reference materials out there, I see that a lot of the time, variables are named _variable in the .h file, then are #synthesize'd in the .m file as
#synthesize variable = _variable;
Why is this done? What am I missing?
Thanks!
There is not consensus on this. Some people like to use it for clarity to separate out class variables, and as another responder noted to avoid conflict with incoming parameter names. Even in Apple sample code the use is mixed.
However, I greatly prefer to not use the _ prefix and have two strong reasons:
1) Some people think the _ is a good indicator of "private". My take is that NO class local variable should be accessed without a setter/getter (property) and thus they are ALL private - given that why not name them in a way easier to read and use autocomplete on? Any overlap in names from parameters is quickly revealed by the compiler, and avoided through more thoughtful naming of parameters (or internal variables).
2) (even better reason) - if you use "refactor" in XCode on an internal class var that is named the same as the property used to access it, the property and synthesize statement will also be renamed. If you use refactor on a class variable prefixed with an _, the property name will not be changed - just the synthesize mapping to the internal name. I pretty much never want the name to vary from the property to the real variable it exposes access to. That alone makes me never want to use _ as a variable prefix, since being able to shift names is just about the most useful thing you can do to improve code clarity.
Using that syntax is an option to make it more clear that the ivar and property are different things.
To code external to the class, there is no difference since it uses the property.
For code in the implementation of the class itself, it can make it more clear when the ivar is used versus the property.
For example, say we have an ivar/property for an NSNumber object:
#interface MyClass : NSObject {
NSNumber *num;
}
#property (nonatomic, retain) NSNumber *num;
- (void)doSomething;
#end
#implementation MyClass
#synthesize num;
- (void)doSomething {
// set the property, num is properly retained
self.num = [NSNumber numberWithInteger:1];
// accidentally set the ivar, num is NOT retained
num = [NSNumber numberWithInteger:2];
}
#end
and now using a different name for the ivar and property:
#interface MyClass : NSObject {
NSNumber *i_num;
}
#property (nonatomic, retain) NSNumber *num;
- (void)doSomething;
#end
#implementation MyClass
#synthesize num = i_num;
- (void)doSomething {
// set the property, num is properly retained
self.num = [NSNumber numberWithInteger:1];
// compiler error, there is no ivar named "num"
num = [NSNumber numberWithInteger:2];
// set the ivar, so it needs to be a retained object
i_num = [[NSNumber alloc] initWithInteger:3];
}
#end
Previous answers are missing the history behind this. Before Objective-C 2.0, there were no properties. So you’d have an object with instance variables like this:
#interface MyObject: NSObject {
NSArray *myArray;
}
#end
But how would you access them from other objects? the solution was to make setters and getters. But to avoid confusion, they would do it like this:
#interface MyObject: NSObject {
NSArray *_myArray;
}
- (NSArray *)myArray;
- (void)setMyArray:(NSArray *)myArray;
#end
The _ serves to clear up confusion between the instance variable _myArray and the method -myArray.
Sometimes people use mVarName (C++) and in Obj-c the style seems to be _varName.
One problem you can have, is imagine that your argument to a function is ...set:(int) x - BUT - you have an iVar called x...well your going to get the compiler crying about stuff like that - not to mention its confusing.
The m,_, whatever helps to show what are member properties of the class.
-(void) set:(int)x
{
x = x; // x is an ivar! heh
}
VS
-(void) set:(int)x
{
_x = x; // ahh I see!
}
This is purely convention. I suppose its common because when you make a method getter call like this:
[myObject variable]
you are actually calling a method, not accessing a variable directly. the _ in front makes it clear that you are talking about a variable. Personally, I find this syntax annoying and distracting. I find it unnecessary, but you are right, it does appear here and there.
I prefer not to use the '_' prefix because Apple does use it consistently. By avoiding the prefix I then have greater confidence that my ivars do not collide with Apple's when I extend a cocoa touch class. Since we do not have access to the base class' source this is really the only way I know of to avoid accidental reuse of existing private ivars.
Much like
Method names beginning with “_”, a single underscore character, are reserved for use by Apple.
My preference, following Google, is simply to append an underscore and explicitly synthesize (even if I'm reimplementing):
#synthesize varName=varName_;
If I see that trailing underscore outside of init..., dealloc or an accessor, I know something's fishy.