property without retain with example - objective-c

if we use a property without the "retain", what does it change? i have this example :
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
- (id)initWithCoordinate:(CLLocationCoordinate2D) coordinate;
in the .m :
-(id)initWithCoordinate:(CLLocationCoordinate2D)coord{
coordinate = coord;
return self;
}
the "retain" is normally used for the setter, isn't it? so here, we use the setter, in initWith..., but we don't use "retain"... any idea?
Thanks

CLLocationCoordinate2D is not an Objective C object, so attempting to send retain and release to it doesn't make sense.
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
This declares an assign read only property, which is the only correct thing to do for a property with a plain C type. Additionally you have said it is nonatomic which means that there is no code to synchronize the property. Since the property is a struct consisting of two 64 bit values, that probably means that you can get an inconsistent result back if you read the property at the same time as some other thread is changing it.
the "retain" is normally used for the setter, isn't it? so here, we use the setter, in initWith...
No, you don't actually. The line
coordinate = coord;
actually assigns the instance variable directly. However, this is what you want in this case. If the property was not read/write and was an Objective-C object type, it would still be assigning the instance variable directly. In that case, you'd need one of the following.
[self setCoordinate: coord];
or
self.coordinate = coord;
or
coordinate = [coord retain]; // in init only
By the way, your init is wrong. It should follow the pattern:
-(id)initWithCoordinate:(CLLocationCoordinate2D)coord{
self = [super init]; // assuming init is the designated initialiser of the super class
if (self != nil)
{
coordinate = coord;
}
return self;
}

In your specific case, readonly means that you class allocates the object and then gives access to it through a property that does not allow this property to be changed from outside.
In general, the object will be nevertheless retained by the class when it allocates it, and released when dealloc is executed.
In your case, the object of type CLLocationCoordinate2D is copied when assigning to the ivar:
coordinate = coord;
because it is not a pointer object, rather a simple struct made out of 2 doubles:
typedef double CLLocationDegrees;
typedef struct {
CLLocationDegrees latitude;
CLLocationDegrees longitude;
} CLLocationCoordinate2D;
So, that is the reason why you don't see any retain in the code. If instead of being a CLLocationCoordinate2D object, it had been an NSString you would have probably needed a retain when doing the assignment to the ivar. (I say "probably" because it all depends on the ownership of the assigned object).

The retain property is used for objects that need to be (surprise) retained. That is: your objects needs the object assigned to the property to stay around, it may not be deallocated.
In your case, it wouldn't change anything as a struct, not an object.
But what you're using in the cited code is readonly, and that means there is no setter, only a getter.

Related

Can anyone explain the synthesize process when using Objective-C?

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
}

Objective-C : Need advice on setting instance variables in init method

I am using ARC.
This is my .h file
...
- (id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t;
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
#property (nonatomic, copy) NSString *title;
...
This is my .m file
....
#synthesize coordinate, title;
- (id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t
{
self = [super init];
if (self) {
coordinate = c;
[self setTitle:t];
}
return self;
}
....
Is setting coordinate this way, the right way to do it? Given that I declare it as readonly, it seems like it is the only way to do it. What if I just use the default (i.e. readwrite), in this case, should I use the setter method [self setCoordinate] instead?
I could set the title by doing title = t as well. Compare to using the setter method, the result is the same, but what is the difference ?
Thanks! Wish I could accept all of your answers.
You're actually supposed to set ivars directly in an initializer method all the time. This is true whether or not you have a readonly or readwrite property. The documentation here even says so.
The reasoning behind this has to do with inheritance. If someone were to subclass your class and overwrite the setters for your properties such that they bypass the ivars you created (or do some other wacky thing), then suddenly your original implementation of your initializer method now no longer does what it is written to do. In particular, your initializer could end up creating an object with a weird state due to the subclass overriding your accessors. In the pre-ARC days, you could also end up with tricky (or just straight-up broken) memory situations when this sort of thing happens. The take-away message is: you should write initializers so that they will always create an object with a known valid state.
So (assuming you're using ARC) your initializer should actually be:
- (id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t
{
self = [super init];
if (self) {
coordinate = c;
title = [t copy];
}
return self;
}
Personally, I prefer to synthesize ivars with a starting underscore to clarify when I'm using the property and when I'm accessing the ivar directly (LLVM 4.0 now does this to automatically synthesized properties as well).
#synthesize coordinate = _coordinate;
#synthesize title = _title;
- (id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t
{
self = [super init];
if (self) {
_coordinate = c;
_title = [t copy];
}
return self;
}
1: As your code is now, yes, that is the right way to do it. If you weren't using ARC (assuming you are currently), you'd also want to retain the value to assert ownership. This will be done automatically under ARC. Keep in mind that that is not the only way of doing it; you could redeclare the property as readwrite in the class extension in the implementation file. This is a common practice which allows you to have the benefits of a readwrite property while having the property still be readonly to users of the class. Ex.
//MyClass.h
#interface MyClass : NSObject
#property (nonatomic, strong, readonly) NSNumber* number;
- (void) initWithNumber:(NSNumber*)number;
#end
//MyClass.m
#interface MyClass ()
#property (nonatomic, strong, readwrite) NSNumber* number;
#end
#implementation MyClass
//this changes the instance variable backing the property to _number.
#synthesize number = _number;
- (void) initWithNumber:(NSNumber*)number{
self = [super init];
if (self) {
self.number = number;
}
return self;
}
#end
At the end of the day, I'd say it's a good habit to use setters whenever you can to keep things KVO compliant and so that you always know when values change. For instance, if you have a custom UIView with a property that is reflected in its appearance, chances are you'd want to redisplay yourself when it changes. The easiest way to do this is to implement the setter yourself and call setNeedsDisplay after setting the value. You couldn't do that if you set the instance value backing the property directly; the user of the class would have to remember to call setneedsDisplay every time they set it, manually.
2: One goes through the setter method, giving you a way to know when a value is going to be set, while one sets a value to the instance variable backing the property. The setter method will always handle memory management in the way it was told to, while it's up to you to do things such as copying values for a copy setter if you assign directly to an instance variable, so that you maintain some consistent scheme. Going through setters sometimes, and not others can lead to some nasty bugs if you don't be careful. Never going through setters makes it hard to know when values change, making it near impossible to weed out invalid values. For instance, if you had an int property you wanted to limit to values in some range and someone passed in a value under the minimum limit, you'd probably want to set the property to the lowest possible value in the range. You can't do that without the value going through the setter first.
Yes, it is fine to set it like that. If you prefer to use a property all the time you can override the property to be read/write rather than read-only in a class extension. In Foo.m:
#interface Foo ()
#property (nonatomic) CLLocationCoordinate2D coordinate;
#end
#implementation Foo {
// ...
self.coordinate = c;
}
Setting the coordinate that way is correct, and is the only way to do it if you have declared the property readonly.
Setting the title using title = t is different than setting the title using [self setTitle:t]. If you directly assign to the instance variable, you will just retain the NSString instance that was passed as argument t. But if you using the accessor method, the accessor will ask the string to copy itself (because you declared the property copy). If the string you were given as argument t is actually an NSMutableString, then you will get an immutable copy of it. If the string you were given as argument t is already an immutable string, it will just return itself when asked for a copy.
self.coordinate = c;
is essentially compiled to be the same as calling
[self setCoordinate:c];
The difference between coordinate = c and [self setCoordinate:c]; is that the first is just setting a variable directly where as the second is calling a method.
The reason to be wary is that methods could potentially have side effects depending on how the implementation is written e.g. (stupid example)
- (void)setCoordinate:(CLLocationCoordinate2D)coordinate;
{
_coordinate = coordinate;
[self doSomethingCrazy];
}

Why the setter is called for one property but not the other?

I took this code from the Big Nerd Ranch iOS Programming book. In the code, they are assigning two instance variables, coordinate and title. Why is coordinate assigned directly, and title is set by calling a setter?
Header File
#interface BNRMapPoint : NSObject<MKAnnotation>
-(id)initWithCoordinate:(CLLocationCoordinate2D )c title:(NSString *)t;
#property(nonatomic, readonly) CLLocationCoordinate2D coordinate;
#property(nonatomic, copy) NSString *title;
#end
Implementation File
-(id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t
{
self = [super init];
if(self){
coordinate = c;
[self setTitle:t];
}
return self;
}
Two reasons, the most important of which is that there is no setter for the coordinate property. It's declared read-only, so there is only a getter method generated.
The second is that CLLocationCoordinate2D is a struct, not an object. There are memory management actions (copying, in this case) that have to be taken for the title object; the simplest way to make that happen is to use the already-existent setter method. The compiler takes care of moving the data for a POD type like CLLocationCoordinate2D.
If the second were the only reason, however, this would be a poor decision -- that's bad style to use the setter for one property and not for the other.
There is a school of thought that says you should copy NSStrings. They're invoking the setter on the string to get that copy. However, there's no need to copy (or even retain) the coordinate, as Josh points out.

#property and #synthesize and memory bugs

I'm beginner in Objective C and Cocos2D
I read Features of use #property and #synthesize (cocos2d)
The comments were references to bugs in the memory. What are these bugs?
In my code I use:
//interface
{
CC_bla_bla *a;
}
#property(nonatomic, retain) CC_bla_bla *a;
//implementation
#synthesize a;
self.a=[CC_bla_bla load_value:123123]
//dealloc
[self.a release]
self.a = nil;
Within a class, I always use self.a for all manipulations. Is that bad?
And in what sense to use the "instance variable" a?
Properties are most commonly used for getting things to and from other view controllers. You can use properties just in a certain view controller but you have to be cautious.
Since you do:
#property(nonatomic, retain) CC_bla_bla *a;
That has a retain count of 1 which like you did, you must release it in the dealloc. But say you do a = [[CC alloc], etc.... Then it will have a retain count of two.
Hopefully you understand this. You will realize on your own when it is time to use properties.
Properties are just there to associate some "metadata" to your variables which will be used when you access to this one via the object. The #synthesize directive will generate the getter and the setter of the variable using the properties config.
For example:
self.a = [CC_bla_bla load_value:123123]; // The object is retained because of the property
// This is equivalent to the previous line
[self setA:[CC_bla_bla load_value:123123]];
// ------
// By the same way
self.a;
// is equivalent to
[self a];
// ------
// method generated by your property
- (void)setA:(CC_bla_bla *)newA
{
[newA retain];
[a release];
a = newA;
}
But if you use directly the variable without passing by the object you don't use the properties value. For example:
a = [CC_bla_bla load_value:123123]; // The object is not retained so you may have unexcepted behaviors
// A good solution
a = [[CC_bla_bla load_value:123123] retain];
I hope it'll help you to clarify some points. For further reading you can watch this tutorial.
I think you are doing right with your code.
call your property always with self. is good.
But be ware, your code is fine only if the [CC_bla_bla loadvalue:] is not retain the created objects. If your loadvalue function have retained the created object and a property would retain it again, then it should be released twice.

Objective-C, interface declarations with properties

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.