views:

4840

answers:

2

A 101 question

Let's say i'm making database of cars and each car object is defined as:

#import <UIKit/UIKit.h>

@interface Car:NSObject{
    NSString *name;
}

@property(nonatomic, retain) NSString *name;

Why is it @property(nonatomic, retain) NSString *name;

and not @property(nonatomic, assign) NSString *name;

I understand that Assign will not increment the reference counter as Retain will do. But why use Retain, since name is a member of the todo object the scope of it is to itself.

No other external function will modify it either.

+3  A: 

Without retain there is no guarantee the NSString* you are setting name with will live any longer than the assignment statement itself. By using the retain property for the synthesized setter you're allowing it to tell the memory management system that there is at least one more object interested in keeping the NSString* around.

fbrereto
ok...yeah, I think I'm sorta geting you.Please tell me in detail what you mean please.
qstar
because, if it's alive for the retain method, why not for the assign statement
qstar
The retain ensures that it will *stay* alive, whereas with assign, there is no guarantee of that. Retaining means that you own that object and as long as you own it, it will not be destroyed. Assign gives you no such guarantee.
Dave DeLong
Ahh, nice answer.But then why not use it for other declarations such as for NSInteger types as well.@property(nonatomic, retain) NSInteger *name;
qstar
@qstar: NSInteger is not an object.
Chuck
Opps I meant@property(nonatomic, retain) NSInteger modelID;Let me restat my argument.Why doesn't the same understanding apply for this case?I see often @property(nonatomic, assign) NSInteger modelID;
qstar
Ahh, Thanks ChuckSo primitives are always held in memory!
qstar
Actually, why doesn't the same memory management concept apply to primitive values as well?
qstar
Some types (like NSInteger) are not heap-allocated, so there is no memory that needs to be released. Note that NSInteger is a different type from NSNumber, which does need memory management.
fbrereto
Whether it's allocated on the heap or not is beside the point. `malloc(sizeof(int))` allocates from the heap, but you'll crash if you try to release that. NSInteger is not an object and thus doesn't respond to messages.
Chuck
What do you mean "no guarantee"? Do you mean the memory can just go away on you randomly causing bugs? Or do you mean if somebody did a [ release ] or [ dealloc ] on "the NSString* you are setting name with", then you would be s.o.l.? ALso this is a separate question but a [ dealloc ] will completely destroy the NSString regardless of ref count, T/F?
bobobobo
@bobobobo: If you do not [retain] the `NSString*` it may be deallocated behind your back; your next dereference of it would be to undefined memory. [dealloc] should never be called from within your own code (other than to call [super dealloc] in your own [dealloc]) - all you should need to call is [retain] and [release], and the OS will call [dealloc] when appropriate.
fbrereto
+8  A: 

There's no such thing as the "scope of an object" in Objective-C. Scope rules have nothing to do with an object's lifetime — the retain count is everything.

You usually need to claim ownership of your instance variables. See the Objective-C memory management rules. With a retain property, your property setter claims ownership of the new value and relinquishes ownership of the old one. With an assign property, the surrounding code has to do this, which is just as mess in terms of responsibilities and separation of concerns. The reason you would use an assign property is in a case where you can't retain the value (such as non-object types like BOOL or NSRect) or when retaining it would cause unwanted side effects.

Incidentally, in the case of an NSString, the correct kind of property is usually copy. That way it can't change out from under you if somebody passes in an NSMutableString (which is valid — it is a kind of NSString).

Chuck
You should use copy instead of retain for all classes that has a mutable variant. Eg. NSAArray, NSSet, NSDictionary, NSData, NSCharacterSet, NSIndexSet, and NSString.
PeyloW
As a rule of thumb all properties with object references should use copy or retain, with one exception; delegates are assign to avoid circular references.
PeyloW
Good answer. Another good answer: http://efreedom.com/Question/1-387959/NSString-Property-Copy-Retain
MattDiPasquale