Different between self.myIvar and myIvar? - iphone

What's the difference between referring to an instance variable in an objective-c class as this:
self.myIvar
and
myIvar
if it's been declared as a property in the header and synthesized?

If you refer to self.myVar, it will use the #property declared in your header file.
For example
#property(nonatomic, retain) Class *myClass;
If you have
myClass = [ [ Class alloc ] init .... ];
Retain Count will be 1
But if you use
self.myClass = [ [ Class alloc ] init .... ];
Retain Count will be 2 because of the retain property.
It's the same if you set setter || getter method in the #property.

What's the difference between referring to an instance variable in an objective-c class as this:
self.myIvar
and
myIvar
if it's been declared as a property in the header …
Simple: The former does not refer to an instance variable.
It refers to a property named myIvar. Likewise, the latter refers to an instance variable and not a property.
The property is, of course, misnamed, because a property and an instance variable do not necessarily have anything to do with each other, and indeed a property does not even need to be backed by an instance variable.
Attempting to access self.myIvar is exactly the same as sending self a getter message for the property. That is, these two statements:
foo = self.myIvar;
foo = [self myIvar];
are exactly the same.
Likewise, attempting to assign to self.myIvar is exactly the same as sending self a setter message. These two statements:
self.myIvar = foo;
[self setMyIvar:foo];
are exactly the same.
By comparison, referring to the instance variable myIvar (no self.):
foo = myIvar;
myIvar = foo;
is exactly that: accessing a variable; nothing more.
This means a lot.
The accessors, particularly the setter, tend to have side effects. For example, if the property is declared as retain, a synthesized setter for it will release the old value of the property and retain the new value. Likewise, if the property is declared as copy, a synthesized setter will release the old value and make a copy of the new one.
Since an assignment to a property:
self.myProperty = foo;
is an accessor message, that “assignment” will cause the old value to be released and the new value to be retained/copied.
An assignment to a variable:
myIvar = foo;
being nothing more than an assignment to a variable, will not do that. If you owned the old value of myIvar, you just leaked it, and if you don't already own the new value, you still don't own it, which means it will probably die while you're still holding onto it, leading to a crash later. (See the Memory Management Programming Guide.)
Despite the two looking similar, they are very, very different.
As a general rule, you should use your properties everywhere except init methods and the dealloc method, and directly access the instance variables (where you have instance variables) in those methods. (Again, accessors may have side effects; you're likely to not want those side effects in a half-initialized or half-deallocated object.)
… and synthesized?
That doesn't matter. #synthesize is just one of three ways of telling the compiler how the property's accessors are implemented:
#synthesize: Compiler, you implement them.
#dynamic: Don't worry about it, compiler; my superclass will dynamically supply the accessors at run time. (Most common in subclasses of NSManagedObject.)
- (Foo *) myProperty { … } / - (void) setMyProperty:(Foo *) newFoo { … }: Here are my implementations of the accessors.
Failing to do one or more of those things for a property will get you a warning from the compiler and probably some run-time exceptions, because you never actually stated an implementation for the accessors that (by declaring a #property) you declared the instances would have.

The difference is that ivar is just a variable pointing to a location in memory, whereas self.ivar calls the setter (in the case of self.ivar = x) and getter (for x = self.ivar) methods. IE, under the hood, the self.ivar in these statements gets translated into [self setIvar:value] and [self getIvar] respectively . These methods can then handle things like retain/release and any class-specific behaviour on your behalf, and in fact do so by referencing ivar directly. The #synthesize keyword automatically generates these getter and setter methods for you to cut down on boilerplate code.
So, ivar is a location in memory where your object can store something, and self.ivar wraps class methods around that location in memory to manage access to it. Note that when initializing an object it is usually preferable to set the ivars directly to avoid possible strange behaviour with not-quite-fully-formed objects.

Without the self. part you'll be accessing/assigning the actual data member of the class, without going through the getter/setter generated by #synthesize (or you can write your own getter/setter if you need something more fancy than the default behavior).
Note that in those custom accessors you'd pretty much have to omit the self. part to avoid endless recursion, e.g. if you have a string property called s, a setter could be (this is similar to what is generated when you do #synthesize, by the way):
-(void)setS:(NSString *)newVal
{
if(newVal == s) return;
[s release];
s = [newVal retain]; //if you use self.s here, setS will be called again
}

self.ivar
calls a property method that you can later change or add to, and that might do some memory management as well. For instance, you could make setting self.ivar also change ivar2, increment ivar3, bounds check ivar4, send a message to object5, release object6, play sound7, etc.
ivar
just reads or writes some number of bits in memory.

Related

"Copy" when using ARC

I know that when using ARC and you have an NSString property, you do #property(nonatomic, copy) just as you would MRC. But I'm wondering, after I converted my project to ARC, I still have this in my initializer method:
_someString = [someStringParameter copy]
Is this a bug? Or even with ARC, do I still need to explicitly say "copy" ? Or should I just do:
self.someString = someStringParameter
and all will be OK? Bit confused here...
You'd never use self.someString = anything in your initialiser. The dot notation is a method call. You shouldn't call methods on classes that aren't fully instantiated yet. Most demonstrable failure case: a subclass overrides setSomeString: — where is it in its init when that method is called?
ARC will handle proper retains and releases on instance variables but can't automatically do copies — e.g. there are __strong and __weak modifiers but no __copy. So you still need explicitly to copy when doing a direct instance variable assignment.
_someString = [someStringParameter copy];
Is this a bug?
No.
Or even with ARC, do I still need to explicitly say "copy" ?
Absolutely.
You're assigning the instance variable by copy and it's perfectly legit under ARC. As opposed to that, doing just:
_someString = someStringParamenter;
will cause ARC to automatically retain (not copy) it, resulting in something like
_someString = [someStringParameter retain];
This happens because under ARC variables have an implicit __strong identifier unless specified otherwise.
self.someString = someStringParameter
This is right, and both under ARC and MRC you'll get the object to be copied if you provided the copy attribute in the property declaration.
That said, it's still a bad idea to use accessor methods in initializers, since they may have unwanted side effects in case you have a custom implementation for them. Check out this answer on the subject: Should I refer to self.property in the init method with ARC?

Setters and Getters on ARC environment

I am still learning some nuances of CocoaTouch. What kind of getters/setters are generated internally for types like float, int, etc., on an ARC environment?
I know that if the property is an object on a non-ARC I may have something like this:
- (NSURL *)url {
if (_url == nil)
_url = [[MyURL alloc] initWithURL:url];
return _url
}
- (void)setUrl:(NSURL *)theUrl {
if (theUrl != _url) {
[_url release];
_url = [theUrl retain];
}
}
but on an ARC environment release and retain cannot be used. What kind of getter/setter is created automatically for an ARC environment on this case.
And what about scalar type like float, int, etc.?
ARC handles all the releasing and retaining for you. You should probably just use synthesized getters and setters, but if you aren't doing that, just set the ivar and remove all the other code.
A couple of thoughts:
The accessor methods (the getters and setters) for fundamental data types (int, bool, etc.) are very much like the standard accessor methods for objects, the only difference being is that there are no memory management semantics, as they don't make any sense except within the context of an object. Thus, you'll see no strong or weak with these fundamental data types. And thus the concept of retain is not applicable, either.
Behind the scenes, the system generated setter for an object declared as a strong property in ARC is not dissimilar to the setter for a retain property of an object in non-ARC code. It increases the retain count (a.k.a. "maintains a strong reference"). Now, clearly if you were writing the ARC setter for your strong property yourself (which you really shouldn't do), you wouldn't be writing that line of code that says retain, but the compiler is effectively doing that for you behind the scenes.
I'm not quite sure to make of your getter method, as it doesn't quite make sense. Generally getters are not doing any alloc or init for you.
Your setter is a little closer (and I assume this was for a #property declared as retain). Clearly, the automatically synthesized setters will automatically pick up the memory lifetime qualifier (e.g. retain vs. assign vs. copy vs. ...) and generate the appropriate code for you, so it's better to just let it do its own thing.
By the way, the actual system generated setter will also include KVO (key-value-notification) calls, too. You don't need to worry about what KVO is, but the key thing is that you don't want your code littered with your own hand-written setter methods, because when you start using KVO, you'll regret having done so. This is just another reason to let the compiler synthesize it's own accessor methods.

What exactly is a property in Objective C ? What is the difference between a property and an instance variable?

I am very much confused between instance variables and property. I have read number of posts regarding this but still i am not clear about it.
I am from JAVA background and what i infer from objective C documentation is that a property is similar to JAVA BEAN CLASS (one having getter and setter of instance varibles). A property can accessed from other classes through its getter and setter methods while an instance variable is private and cannot be accessed from other classes.
Am i right in thinking in this direction ?
The parallel with Java is very good. The only difference is that Objective C provides a way to access a property as if it were a variable, and Java does not. The other difference is that in Objective C you can synthesize properties, while in Java you need to write your getters and setters manually.
Property is a "syntactic sugar" over a getter method or a pair of a getter and a setter methods. Properties are often (but not always) backed by an instance variable, but they can be implemented in any way that you can implement a parameterless instance method.
Ok, instance variable and property is far away from each other. instance variable is a state of object and property is a assecor method(getter/setter) of that state(instance variable).
So whenever you create an property in header file. compiler convert those property in to accessor method. suppose you declared property - #property(nonatomic, assign, readwrite) NSString *name;
So compiler will be converted those in to
-(NSString *)name;
-(void)setName:(NSString *)name;
And then for definition for accessor method there is two way.
manually - use dynamic in implementation file(.m) and then give the definition of accessor method by doing this you won't get any warning.
Let compiler do the job - this can be done by synthesizing property e.g synthesize name;. so now compiler will generate the definition for the accessor method for you.
Hope it helps ;)
I know this subject has been beat to death here ... but some seem to be focusing on the technical details, whereas I wanted mention something along the lines of the BIG PICTURE ...
Think of properties as kind of first-class ivars. Both properties and ivars may model attributes of an object ... but an ivar gets special attention if you go ahead and set it up as a property. Basically, you should an attribute as a property (as opposed to an ivar) if you feel it needs getter / setter methods. Dot notation makes for very readable code. This may help in deciding when to declare a variable as a property as opposed to simply using a regular ivar.
A property in objective c is in fact the setter and getter methods that make it possible to access an attribute in a class from outside of it. So when you declare for example
#interface example:NSObject{
NSString *variable;
}
#property(readwrite, assign) NSString *variable;
#end
#implementation
#synthesize variable;
#end
You are in fact declaring the methods
-(NSString *)getVariable;
-(void)setVariable(NSString *)value;
And you can access then by using the point notation and the name of the property, like
instance.variable = something;
something = instance.variable;
The primary difference between instance variable and property is that for properties, the compiler will automatically generate a getter/setter method pair. For instance:
#property (nonatomic) int value;
will generate:
-(void)setValue:(int)i
{
value = i;
}
-(int)value
{
return self->value;
}
given #synthesized.
If you crab a book on Objective-C 1.0, you'll notice that this feature isn't available. This is a new feature in 2.0, also known as the dotted syntax. It's introduced mainly because the complicated getter/setter syntax.
The benefit of this feature is that even though you have the compiler automatically declared the pair for you, you can still manage to override it. For instance, you can still have -(void)setValue:(int)i declared as a method of your class, and override the behavior. This is useful in scenarios of validation, such as you want to put a limit on the range of value.
As far as Java is concerned, Objective-C actually do have #public instance variable syntax, but it's a habit not to use it. It's sort of similar to Java's concept of protecting a private variable through getter/setter. But its primary objective-c is to override getter/setter and minimize syntax.
Now this is just a preview, refer to http://cocoacast.com/?q=node/103 or some objective-c 2.0 books if you wanted to know more.
Well, maybe it was not clear that a property does not need an instance variable.
You can define a read-only property based on any calculation on instance variables or any other variables in the scope. The issue here is that you must manually code the getter.
#interface person:NSObject{
NSDate *birthDate;
}
#property(readonly) int age;
#end
#implementation
-(int) age{
// return calculated age based on birthDate and today;
}
#end
The name of the property does not need to be the same as the instance variable.
#synthesize myProperty = myVar;
I found this amazing thread which clearly explains each and evrything about properties.
http://www.iphonedevsdk.com/forum/iphone-sdk-tutorials/7295-getters-setters-properties-newbie.html
Thank you all for your responses.

What's the difference between self.propertyName vs. propertyName?

The title says everything!
In Objective-C, what's the difference between self.propertyName vs. propertyName?
self.propertyName is sending the object a message, asking it for the value of propertyName, which means it may go through a getter/setter, etc. propertyName is directly accessing the ivar, bypassing any getter/setter. Here's an article going into it in rather more detail.
self.propertyName increse the retain count by one if you have specified the propertyName as retain in property declaration
propertyName will not increase the retain count an could lead to the crash of application.
e. g. ,
#property (nonatomic,retain) NSString* propertyName;
lets say you have nameProperty NSString object.
Below increase the retain count by 1 and you could use self.propertyName and call release.
self.propertyName = nameProperty;
[nameProperty release];
Below does'nt increase the retain count so if you use propertyName in your application it will result in crashing of your application.
propertyName = nameProperty;
[nameProperty release];
Any further use of propertyName will result in crash.
self. runs through your likely synthesized accessor methods if you are using properties
ie self.propertyName = newName is the same as [self setPropertyName:newName]
This becomes important for memory management as propertyName = newName would cause you to loose reference to the previous contents of propertyName
If you call self, you can be sure you're calling the class/object that owns the property.
You may find this useful too:
Assigning to self in Objective-C
dot notation is turned into a method call by the compiler. This means that there is extra work at run time for executing this method call, like copying something from and to the stack memory and executing a jump in machine code.
the instance variable by itself is faster because it is essentially just a memory address or scalar value (like int).
One would prefer the self.something notation when you want or need an extra layer to do something. Like retain an object that is passed in or lazily instantiate an object on the first time you need it.
Setting the value of the property does just that - it sets the value of the property directly without going through any accessors or synthesized accessors.
By calling the accessor through self you are going through the accessors. For properties that have been declared with retain or copy it will retain or copy the value that is passed in. For non objecte properties, the usual declaration is assign which means that there is no memory management applied to those iVars.
You see both types of calls - but it is preferred to use the direct method in initialisers and the dealloc method, because calls to self are discouraged in these methods.
If you have declared and synthesized the property, the call to self also generates the KVO notifications for changes in that variable. This saves you having to write the willChangeValueForKey: and didChangeValueForKey: methods.

Objective-C Properties in iPhone Development

Whats the difference between a property and an instance variable in Objective-C. I need to understand this in OOP terms. Is a property declaration just a convenience wrapper (with #synthesize in the implementation) for accessing instance variables?
thanks,
codecowboy.
Properties and ivars are two completely different things.
And instance variable is a variable stored inside the object, so each instance has its own. It is referenced by pointer addition relative to the object pointer/self (slightly indirected for the modern runtime, but functionally equivalent). ivars are generally internal to a class, and by default can only be accessed by the class and its descendents (#protected). Within methods they are available with no qualification, otherwise they can (but rarely are, ad usuaually should not) be accessed via indirection, eg obj->ivar.
A property defines a getter and setter (the setter is optional) interface. That's all it does. It defines two public methods:
- (TYPE) propname;
- (void) setPropname: (TYPE) newPropname;
These are defined as methods exactly as if you declared them like that, no more, no less. These methods are called either with the normal syntax ([obj propname] and [obj setPropname:n] or using the modern dot notation (obj.propname or obj.propname = n). These two options are syntactically different only, they behave identically, and you can use dot notation whether the methods are declared with #property or declared manually as above.
You must then implement the methods in the implementation, either by writing the methods yourself, by using #synthesize, or by handling the missing method dynamically.
Properties may be backed by an ivar (named the same or named differently (my preference to avoid confusion)), or they may not. They may store their value elsewhere, or they may calculate it from other data.
For example, you might have:
#property (nonatomic, readonly) NSString* fullname;
and then implement - (NSString*) fullname to return the concatenation of firstname and lastname.
I think you are pretty much there. The #property and #synthesize make the accessor declarations and implementation for the already declared ivar. You have various attributes you can define on the #property too giving you control over how it is generated to make it appropriate for the ivar
Have a look at "Objective C 2.0 Declared Properties"
The difference between Property and Instance ivar is, the variable which make as Property that can be visible in another Class whereas for accessing the iVar or instance you need to create the Object of that class and then you can access.
and With use of #synthesize compiler will generate the setter and getter for that property.
-(TYPE)name;-getter Method
-(void)setName:(TYPE)aName; setter Method