Should I use #property (retain) for a #dynamic property setter that is retaining? - objective-c

I have the following code for a property whose getter/setter I write manually using the #dynamic keyword:
#property (nonatomic, retain) NSObject* obj;
#dynamic obj;
-(NSObject*) obj
{
return obj;
}
-(void) setObj:(NSObject*)newObj
{
[obj release];
obj = [newObj retain];
}
My question is, if I remove the retain from the #property declaration, the compiler complains that the default will be assign and that it may not be what I want. If I add the retain, I assume it is going to be ignored, because I wrote the getters/setters myself?
Just looking for a quick confirmation on this.

You are correct, but your property declaration is as much for documentation as it is for your implementation, at least in this case. At some point, someone (you in six months?) will look at your .h file and say, "Why isn't this value being retained? How does this not crash every time it gets run or leak memory like a sieve?"

The retain allows your object to stay allocated in memory until you apply
[obj release];
so even if you do have your own setter and getter you need to keep the retain to keep your place in memory, because in the end you only have a pointer to that position and that is why the compiler tels you that you may modifying another object or what ever takes the place of your object.
And its important that you make the release to free the memory when you are done using it.

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
}

#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.

Are getters the same for all properties in objective-c?

This simple question is bugging me. Are getters the same for
#property (nonatomic, retain) NSString *name
#property (nonatomic, copy) NSString *name
- (NSString*) name{
return name;
}
According to the documentation
A property declaration, however, provides additional information about
how the accessor methods are implemented (as described in “Property
Declaration Attributes”).
Both the getter and the setter behavior are defined by property declarations. In your example that is correct since it is defined nonatomic but if nonatomic were missing from the declaration it would would be implemented similar to this
- (NSString*) name{
[_internal lock]; // lock using an object-level lock
id result = [[name retain] autorelease];
[_internal unlock];
return result;
}
This of course is only true if you use #synthesize and do not override or change the getter and setter methods.
Yes, as the other answers state, the getters are the same. The options retain, copy, and assign determine how to generate setters, but not the names even of those.
If you want to use a different getter name, for instance if you have a BOOL such as the UIApplication property idleTimerDisabled, then you do this by specifically assigned the getter name:
#property(nonatomic, getter=isIdleTimerDisabled) BOOL idleTimerDisabled
Without an override such as this, the getter name is always the property name.
Yes, they are the same. retain, copy, and assign only give the compiler instructions on how to generate setters, not getters.
Yes, copy and retain only affect the setter and not the getter. On a side note, you should chose copy instead of retain for immutable objects like NSString.
If you're using ARC (Automated Reference Counting), then the getters should all look like what you have above. However, the new standard with ARC is to use strong and weak instead of retain and assign, respectively. retain and assign will still work and are synonymous with the strong and weak, but any newly generated files will use those words instead, so it's important to understand what they mean.
If you aren't using ARC (still an option, even in iOS 5 and Lion) getters can be different depending on retain, copy, or assign.
retain and copy both look like:
- (NSString *)name {
return [[name retain] autorelease];
}
assign is pretty basic, but is usually used more for weak references (like delegates):
- (id)delegate {
return delegate;
}
I went into some detail on this because it's important to understand when using ARC, the code for all 3 look the same, but the behavior is still very much like what's written above. If you're using atomic instead of nonatomic then you need to add some locking/unlocking lines to make the method thread-safe. In any case, it's generally better to use the default accessors generated with #synthesize unless you want to do something really tricky.
Yes, they are. The getter name dependce only of properties name.

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.

iPhone Question about properties

If you declare a property with a retain attribute, do you need to release the property before you set it to nil?
What does the #synthesize directive do?
You do need to release the (retained) object before setting another object or nil in your property var but this is done by the accessor, if you like this.
self.myVar = nil;
What #synthesize does is to create accessor methods automatically for you (In case you don't define them)
so, if you wrote your property as:
#property (nonatomic, retain) NSObject *property;
then you can think that synthesized accessors will be something equivalent(I said equivalent because we don't certainly know how this is done... for more info read doc below) to the following:
- (void) setProperty:(NSObject *)aProperty{
if(property != aProperty){
[property release];
property = [aProperty retain];
}
}
- (NSObject*) property{
return property;
}
This part is SUPER important and I would suggest to spend as most time available to learn about this. (Also read copy and assign)
Apple doc on Properties
You do not need to release a retained property before setting it to nil as long as you use a setter that does the release for you. If you've declared a property with retain, the synthesized setter will do the release for you. And that brings us to the #synthesize directive. It simply tells the compiler to write the setters and getters for you using the attributes you've specified in #property.
No, in fact you don't need to release it at all. That would be a bug. You don't even have to set it to nil, unless you really want to control when it's released (before your own class' release, that is).
Creates the getter and setter methods for you, presumably in an optimized way.
For more information I suggest you read the relevant page in the guide.