In the following common sample,
////
#interface MyObject : NSObject
{
#public
NSString * myString_;
}
#property (assign) NSString * myString;
#end
#implementation MyObject
#synthesize myString = myString_;
#end
////
why declare myString_ in the interface at all?
I ask because we can still get and set myString in the implementation using self.myString, [self myString], self.myString = ... and [self setMyString:...] and in fact we must if instead it's being retained.
This is a matter of preference/convention for some. By default, doing:
#property (assign) NSString * myString;
...followed by:
#synthesize myString;
...will give you three things. You get a setter method that can be accessed as self.myString = #"newValue" or [self setMyString:#"newValue"], a getter method that can be accessed as NSString* temp = self.myString or NSString* temp = [self myString], and an instance variable named myString that be be accessed directly inside of your class (i.e. without going through the getter and setter) and used to set and get the property value, and which is used internally to back the property.
If you like you can do #synthesize myString = someOtherVarName, and then you still get the setters and getters just as before, but instead of the myString instance variable the someOtherVarName instance variable is used to back the property, and no myString variable is created.
So why ever use the more verbose syntax? There is never any case that requires that you do so, but some people prefer to do so when dealing with properties that are declared retain or copy. The reason for this being that setting a property declared retain or copy via its generated setter method will affect the retain-count of the object being set/unset. Doing the same thing by accessing the instance variable directly will not.
So by aliasing the instance variable to something else, you can make a distinction in the code along the lines of "anything that does xxx.myString = Y is modifying the retain count, while anything that does someOtherVarName = Y is not". Again, it's not necessary to do this, but some people prefer to.
You should be able to skip it. Modern compilers allow that.
When you define a property, you are actually declaring how the getter and setter methods are constructed for a particular instance variable. Earlier it needed the instance variable to be defined so you declared it. It also allowed the property name to differ from the instance variable name via #synthesize myProperty = myIVar;. Now you don't need to do this as the modern compilers generate the instance variable for you.
The dot syntax is actually a convenience thing as you would've noticed. It doesn't directly refer to the instance variable but the methods myProperty and setMyProperty:. You can even call myArray.count where count isn't a property (I wouldn't recommend it even though lot of people seem to like it).
While there is a difference between the two, the gap seems to be slowly closing.
That's just a problem about point of view. If you access ivar directly, it's you're accessing it internally. If you're using property, you're not accessing ivar (semantically). You're using accessing method of the object. So you're handling the self as like external object which the internal is unknown.
This is encapsulation problem of Object-Oriented paradigm.
And I recommend some tricks when using properties.
The ivar declaration is optional, not required. Compiler will generate it automatically.
You should set the ivar as #protected or #private to encapsulate it correctly. (at least there is no reasonable reason)
I recommend to use nonatomic if you don't need threading lock when accessing the property. Threading lock will decrease performance greatly, and may cause strange behavior in concurrent execution code.
You can use this code to do same thing.
#interface MyObject : NSObject
#property (assign,nonatomic) NSString * myString;
#end
#implementation MyObject
#synthesize myString;
#end
And this will be transformed roughly something like this.
#interface MyObject : NSObject
{
#private
NSString* myString; // Ivar generated automatically by compiler
}
#end
#implementation MyObject
// Methods with thread synchronization locking generated automatically by compiler.
- (NSString*)myString { #synchronized(self) { return myString; } }
- (void)setMyString:(NSString*)newMyString { #synchronized(self){ myString = newMyString; } }
#end
In fact, I'm not sure about synchronization lock with assign behavior directive, but it's always better setting it nonatomic explicitly. Compiler may optimize it with atomic operation instruction instead of locking.
Here is reference document about the properties: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html%23//apple_ref/doc/uid/TP30001163-CH17
With the modern Obj-C runtime, declaring the ivar is more of a formality than anything else. However, there are some memory management things to keep in mind.
First, the property declaration for an object type is usually retain, or for strings it may be copy. In either case, the new object is retained.
Given the following code:
NSString *string = [[NSString alloc] init];
myString_ = string;
self.myString = string; // If the property was retain or copy
The second assignment would leak; the first would not. This is because the property would retain something that already has a retain count of 1—it is now at 2. When you release the property in dealloc, the count goes to 1, not 0, so it won't be released. With the first option, however, the retain count stays at 1, so dealloc brings it down to 0.
In your example, leaving the property as assign will make the ivar declaration a formality.
Related
I realize that it automatically creates a setter & getter for you but I'm uncertain how the setter actually "looks".
Also, why is it recommended that we say #synthesize someObject = _someObject; instead of just #synthesize someObject;?
Easy bit first: you don't need to #synthesize at all any more. If you have an #property and you don't synthesise it then one is implied, of the form #synthesize someObject = _someObject;. If you left off the = _someObject then you would have the same thing as #synthesize someObject = someObject;. The underscore version is therefore preferred because Apple has swung back to advocating underscores for instance variables and because it's consistent with the implicit type of synthesise.
The exact form of setter and getter will depend on the atomic, strong, unsafe_unretained, etc flags but sample nonatomic strong setter, pre-ARC is:
- (void)setProperty:(NSString *)newPropertyValue
{
[newPropertyValue retain];
[_property release];
_property = newPropertyValue;
}
Note the retain always occurs before the release. Otherwise the following (which you would arrive at in a roundabout fashion rather than ever writing directly):
self.property = _property;
Would lead to _property potentially being deallocated before it was retained.
A sample getter (also pre-ARC) is:
- (NSString *)property
{
return [[property retain] autorelease];
}
The retain ensures that the return value will persist even if the object it was queried from is deallocated. The autorelease ensures you return a non-owning reference (ie, the receiver doesn't explicitly have to dispose of the thing, it can just forget about it when it's done). If the thing being returned is immutable but the instance variable is mutable then it's proper form to copy rather than retain to ensure that what you return doesn't mutate while someone else is holding onto it.
Check leture 3 of iPad and iPhone Application itunes
_someObj replace a memory location for store your object(a pointer).
Xcode 4 auto #synthesize anyObject = _anyObject; -> So you don't need to write #synthesize anymore.
If you have some other object or _anyMemoryLocation write before in your.m file, you can use #synthesize yourObj = _anyMemeryLocation if you don't want rewrite all name in your.m file.
Setter and getter 2 methods use to set or get your object's value outside or inside your class:
-(void)setObject:(ObjectType *) object;
-(void)getObject:(ObjectType *) object;
The key nonatomic auto generate setter and getter for you.
If you want to implement more method went setObject, you can rewrite it in your.m file
-(void)setObject:(ObjectType *) object{
_object = object; //rewrite setter can done anywhere in your.m file
//Add more method
}
#interface RandomObject : NSObject
{
NSString* someObject; // I know I don't have to explicitly declare. Just to clarify my point.
}
#property (nonatomic, strong) NSString *someObject;
#end
#implementation RandomObject
#synthesize someObject;
#end
Given the code above and Xcode 4.3 is used (hence, no auto-synthesizing), here is my question.
The property/synthesize will create accessors for someObject, namely getter and setter. So if I want to assign a value to someObject, I can do this.
self.someObject = #"Tomato"; // [self setSomeObject: #"Tomato"];
If my understanding is correct, self will send #"Tomato" to setSomeObject method. But what if you do this?
someObject = #"Tomato"; // or maybe _someObject = #"Tomato" if you are doing auto-synthesizing
Directly accessing an iVar object seems like a bad idea, but since someObject is a private variable, within the same class you have access to that, right?
I understand why you would need to use self.someOject if you want to manipulate someObject from another class. But why is it that you'd need to do the same even though you are still in the same class. Why is it that it's a bad idea to directly access iVar.
Generally speaking accessors have more pros than cons and I use them everywhere I can.
The main issue is that every place you reference the ivar directly is another potential place your code will need to change.
For example imagine you have referenced someObject in multiple places throughout your class. Then the requirements change and now you decide that when the value of someObject is assigned you need to so some other work. Due to the fact that you have accessed the ivar directly throughout the class you now have to either duplicate this new code everywhere you assign someObject or refactor. If you was using an accessor you just have one piece of code to change
- (void)setSomeObject:(id)anObject
{
if (anObject != someObject) {
someObject = anObject;
[self doSomeWork];
}
}
You can have the same issue with the getter - imagine you store an array of objects in someObjects - this works great but then later down the line you decide that you don't actually need to store someObjects as it can be dynamically computed from other values. If you have directly accessed the ivar everywhere then this becomes a big chore. If you stick to abstracting someObject behind a getter then all you now have to do is
- (NSArray *)someObjects
{
return [self calculateSomeObjects];
}
This is exactly the idea with non-ARC code, which puts the memory management of the ivar in one place (behind accessors) so that you do not have to litter your code with repetitive code.
The property does more than just assigning an object to the ivar.
If you don't use ARC, the property will auto-generate retain/release code to handle memory management. Just calling someObject = #"Tomato" creates a memory leak (if someObject is assigned)
If your property is atomic, the property will provide thread safety, while accessing the ivar would not be thread safe.
See https://stackoverflow.com/a/589348/1597531 for examples of auto-generated property code.
In Apple's The Objective-C Programming Language p. 18, they make a distinction between setting a variable with self versus instance reference. e.g
myInstance.value =10;
self.value =10;
1. Would these two set different properties named value?
2. How could self work if there are several instances with properties named value?
They also assert, "If you do not use self., you access the instance variable directly." This would mean that the accessor would not be called if you use
myInstance.value =10;
and KVO wouldn't work. Is this true?
3. Using #Property and #Synthesize (with garbage collection), what is the proper way to set properties of different instances? And what good is the self reference?
A numeric example would help me, please.
1 - Would these two set different properties named value?
No, I think you misunderstand what the guide is saying when it makes a distinction between self.value and myInstance.value. In both cases the setter function (i.e., setValue:) is called.
You use self to access your own properties (that is, referencing properties from within functions in a class that you wrote). Like:
#interface MyObject : NSObject
#property( nonatomic ) NSInteger value;
- (void) doSomething;
#end
#implementation MyObject
#synthesize value;
- (void) doSomething
{
self.value = 10;
}
#end
Whereas you'd use myInstance to set a property in some other variable, from outside that class.
MyObject* anObject = [[MyObject alloc] init];
anObject.value = 10;
2 - How could self work if there are several instances with properties named value?
It wouldn't. See above.
They also assert, "If you do not use self., you access the instance variable directly." This would mean that the accessor would not be called if you use myInstance.value =10; and KVO wouldn't work. Is this true?
No. self.value and myInstance.value both call their accessors (setValue: in this case), and KVO will work. What that assertion means is that if you access an ivar from within your own class, not using the accessor, KVO will not work.
#interface MyObject : NSObject
#property( nonatomic ) NSInteger value;
- (void) doSomething;
#end
#implementation MyObject
#synthesize value;
- (void) doSomething
{
self.value = 10; // This invokes the accessor, and KVO works.
value = 10; // This just sets the instance variable, and KVO won't work.
}
#end
Using #Property and #Synthesize (with garbage collection), what is the proper way to set properties of different instances? And what good is the self reference? A numeric example would help me, please.
Just as shown above, use the instance name. self is only used for accessing properties within a class. Examples above.
The best way to under stand self is to think of how it is implemented, as a hidden argument with every method call so the method -[UIView drawRect:] has a c function implementation like
BOOL drawRect:( UIView * self, SEL _cmd, NSRect r ) { }; // of cause : is not legal in c
and calling the method is a little like (ignoring the dynamic look up)
UIView * v = ...
NSRect r = ...
drawRect:( v, #selector(drawRect:), r );
so if you invoke a property in the drawRect: implementation you are doing it for the hidden object parameter called self.
Accessing the instance variable directly will stop KVO from working, but sometimes you want that, for example when initialising them perhaps.
IF you mean automatic reference counting when you say Garbage Collection, most of the time for objects you want them to be strong or copy, immutable strings using copy will be turned into a retain and if it is mutable then you often want a copy to protect against the original being changed underneath you.
One potential issue with strong is that you can end up with circular references where if you follow the links around you comeback to the original object so each object is indirectly retaining itself and you have a catch-22 situation where the object has to release itself before it can release itself. So in these situations you need to use weak. You can usually workout who should retain and who should weak by think about which object conceptually owns the other.
For non-object you have to use assign.
self.property and [self method]; are strictly used within a class to refer to itself. You do not ever refer to the object within itself with anything but self.
On the contrary, use instances of an object to refer to an object from another class. For instance, I would refer to a UIImageView from my viewController in a way like:
UIImageView* imgView = [[UIImageView alloc] init];
[imgView setFrame:CGRectMake(0,0,320,480)];
But if I were editing a subclass of UIImageView that I called, say rotatingImageView:
#implementation rotatingImageView
-(id)init
{
//Super instantiation code that I don't remember at the moment goes here
[self setFrame:CGRectMake(0,0,320,480)];
}
This is just an example of a method.
Once again, you use self strictly within its own class, and you use other variables to reference an instance of another class.
Hope that makes sense.
My big problem was how an ivar and a property could be tied together when they have different names, especially with multiple ivars.
I finally found that if name of property doesn't match name of ivar, a new ivar is synthesized. This is accessed by self.propertyname (within object) or object.propertyname (outside of object), not the declared ivar.
To tie disparate names of ivar and property, equate them as in
#synthesize propertyname = ivarname.
Thanks to
http://blog.ablepear.com/2010/05/objective-c-tuesdays-synthesizing.html
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?
So i have found out that you have to use underscore when synthesizing properties and that doesn't make a single bit of sense to me.
So, let's start.
In our .h file we write this line:
#property (nonatomic) double speed;
In our .m file we do this:
#synthesize speed = _speed;
Why? As far as I know, property makes an instance variable and creates setters and getters for it.
But what the hell does line
#synthesize speed = _speed
do?
As common sense tells me, we assign value in _speed to speed. Okay.
Where did we declare _speed? Why doesn't compiler give us an error? What is it supposed to mean? Why such an obfuscated code?
My questions here:
What happens if I do just
#synthesize speed;
without _speed, will I get error or some bugs?
What is the reason after this syntax? What were they thinking when making it? Where does _speed come from? What is it? Is it a pointer or a real value? What is going on?
Well, _speed is the instance variable used by the property. If you really want to declare it fully, you need to write:
#interface Foo
{
double _speed;
}
#property double speed;
#end
#implementation Foo
#synthetize speed = _speed;
#end
Now Xcode 4.4 is unleashed, most of that stuff is unnecessary and should be omitted for sanity.
Basically, all you have to do is:
#interface Foo
#property double speed;
#end
No instance variable, no #synthetize, and everything still works as before. You can either use self.speed or self->_speed for direct access.
You do not HAVE to do that. It is just common practice. The ...=_speed will create an property named _speed and its setter and getter will be named after speed. That allows you to distinguish between
self.speed = value;
and
speed = value;
because the latter will create a compiler error.
_speed = value;
would be correct in that case.
That helps avoiding retain/release related errors because the setter will retain the object and the simple assignmen will not.
(self.speed = ... will call the setter!)
If you omit the "=_speed" on the synthesize statement then the property will be named "speed" only. If you don't make any mistakes, then this will work perfectly fine.
okay you don't have to do this...
However by doing so means that in your implementation you cannot use the non underscore name of that property, because in fact by doing so you would be getting mixed up with accessing the iVar directly rather then through the property.
So in other words by doing this:
#synthesize myProperty;
In your code you can reference it by myProperty (iVar) or self.myProperty (property - with the access rules - readonly/readwrite, getter, setter etc...) this can of course be confusing if you are using some kind of rules like:
#property(nonatomic, retain, getter = anotherProperty) NSNumber myProperty
By accessing this with myProperty in code, you would expect to get value of anotherProperty
This would only be possible by doing:
self.myProperty
So in Objective-C we can do the following to avoid this:
#synthesize myProperty = _myProperty;
Therefore in code it is actually an error to reference myProperty directly, instead you must do self.myProperty (property access) or _myProperty (iVar access).
Its a naming convention, you don't have to do it. People tend to do this so that they can distinguish between the instance variable and the property.
Usually it goes
.h
#interface myClass : NSObject
{
NSNumber *_speed
}
#property (nonatomic, strong) NSNumber *speed;
.m
#implementation
#syntesize speed = _speed;
Nothing bad will happen -- it's fine to just write #synthesize speed. Using _speed just makes the underlying instance variable _speed instead of speed. Most people do this to keep from accidentally accessing the ivar directly, instead of through thr getter.
From the documentation
#synthesize speed = _speed; will point the property speed to the instance variable _speed.
You do not have to do this. #synthesize speed works just fine.
In environment with manual memory management:
Why do I need an instance variable name at all?
You need to release memory which may be used by your properties in the dealloc
You may use self.field = nil but this approach may cause problems
So you need an instance variable which is used behind this property so you can [_field release]; it in dealloc.
The same if you need to access your property in the initializer.
Why do I need an underscore in the instance variable name?
To never accidentally use ivar directly and break memory management contract for the property
#property (retain) UILabel *label;
...
#synthesize label;
...
-(void)viewDidLoad {
[super viewDidLoad];
label = [[[UILabel alloc] initWithFrame:frame] autorelease];
}
here by accidentally missing self. you made label potential 'dangling pointer'. If you used #synthesize label = _label; above code would produce a compiler error.
Local variables or method parameter names often tend to be the same as the property name - if you use underscored instance variable it won't cause any problems
What is the semantic difference between these 3 ways of using ivars and properties in Objective-C?
1.
#class MyOtherObject;
#interface MyObject {
}
#property (nonatomic, retain) MyOtherObject *otherObj;
2.
#import "MyOtherObject.h"
#interface MyObject {
MyOtherObject *otherObj;
}
#property (nonatomic, retain) MyOtherObject *otherObj;
3.
#import "MyOtherObject.h"
#interface MyObject {
MyOtherObject *otherObj;
}
Number 1 differs from the other two by forward declaring the MyOtherObject class to minimize the amount of code seen by the compiler and linker and also potentially avoid circular references. If you do it this way remember to put the #import into the .m file.
By declaring an #property, (and matching #synthesize in the .m) file, you auto-generate accessor methods with the memory semantics handled how you specify. The rule of thumb for most objects is Retain, but NSStrings, for instance should use Copy. Whereas Singletons and Delegates should usually use Assign. Hand-writing accessors is tedious and error-prone so this saves a lot of typing and dumb bugs.
Also, declaring a synthesized property lets you call an accessor method using dot notation like this:
self.otherObj = someOtherNewObject; // set it
MyOtherObject *thingee = self.otherObj; // get it
Instead of the normal, message-passing way:
[self setOtherObject:someOtherNewObject]; // set it
MyOtherObject *thingee = [self otherObj]; // get it
Behind the scenes you're really calling a method that looks like this:
- (void) setOtherObj:(MyOtherObject *)anOtherObject {
if (otherObject == anOtherObject) {
return;
}
MyOtherObject *oldOtherObject = otherObject; // keep a reference to the old value for a second
otherObject = [anOtherObject retain]; // put the new value in
[oldOtherObject release]; // let go of the old object
} // set it
…or this
- (MyOtherObject *) otherObject {
return otherObject;
} // get it
Total pain in the butt, right. Now do that for every ivar in the class. If you don't do it exactly right, you get a memory leak. Best to just let the compiler do the work.
I see that Number 1 doesn't have an ivar. Assuming that's not a typo, it's fine because the #property / #synthesize directives will declare an ivar for you as well, behind the scenes. I believe this is new for Mac OS X - Snow Leopard and iOS4.
Number 3 does not have those accessors generated so you have to write them yourself. If you want your accessor methods to have side effects, you do your standard memory management dance, as shown above, then do whatever side work you need to, inside the accessor method. If you synthesize a property as well as write your own, then your version has priority.
Did I cover everything?
Back in the old days you had ivars, and if you wanted to let some other class set or read them then you had to define a getter (i.e., -(NSString *)foo) and a setter (i.e., -(void)setFoo:(NSString *)aFoo;).
What properties give you is the setter and getter for free (almost!) along with an ivar. So when you define a property now, you can set the atomicity (do you want to allow multiple setting actions from multiple threads, for instance), as well as assign/retain/copy semantics (that is, should the setter copy the new value or just save the current value - important if another class is trying to set your string property with a mutable string which might get changed later).
This is what #synthesize does. Many people leave the ivar name the same, but you can change it when you write your synthesize statement (i.e., #synthesize foo=_foo; means make an ivar named _foo for the property foo, so if you want to read or write this property and you do not use self.foo, you will have to use _foo = ... - it just helps you catch direct references to the ivar if you wanted to only go through the setter and getter).
As of Xcode 4.6, you do not need to use the #synthesize statement - the compiler will do it automatically and by default will prepend the ivar's name with _.