What exactly is happening when I set an object's property using an accessor method?
Say I have an object called MyClass, which has a property defined as 开发者_Go百科@property (nonatomic, retain) NSString *foo;
and I synthesize that property.
Then in another class, say the application delegate I define a string (but it could be anything) NSString *myString = [[NSString alloc] initWithString:@"Hi"];
and call on an instance of MyClass: [myClass setFoo:myString];
What actually happens? Does the reference to the space that was allocated for myString
get set? Or does it get what is in the allocated memory for myString
and set it to the allocated memory for foo
, since I called retain
on foo
?
And I have to release myString
in the application delegate. And I have to release foo
in MyClass, since it was retained, but do I have to release it again since another alloc'd variable was assigned to it?
It all depends how the property is declared. Because yours is (retain)
, it will keep the same object pointer, and also automatically send -retain
so it can ensure access to the memory whether or not the caller holds a reference. If you used (copy)
, it would send -copy
which would make a new object that's a copy of the old one (provided the object conforms to `NSCopying).
This all happens in the accessories implementation, which is commonly generated for you when you use @synthesize
. If you implement your own, be sure to use the correct behavior!
@synthesize
basically creates two methods for you. In your case those two methods would be similar to this:
-(NSString*) foo;
{
return foo; //synthesized ivar
}
-(void) setFoo:(NSString*)newValue;
{
if(foo != newValue){
[foo release];
foo = [newValue retain];
}
}
However, @synthesize
won't release the value in dealloc
, so you have to do that manually.
Objects in Objective-C are treated as pointers, so when you say NSString* a = b;
you're not copying the object itself, you're just making another pointer to the object. Synthesized properties are no exception to this.
What happens is that the object myString
points to gets its retain count incremented by one when you do [myClass setFoo:myString];
Initially, when you alloc a string and store the reference in myString
, the retain count is 1. Storing it in a property with retain like you have, gets its retain count incremented to 2.
No you don't have to release it again. Max retain count is 2. Hence 2 releases.
精彩评论