开发者

Question about retain and copy in Objective c

This question confused me a little. In the ".h" file.

@property (nonatomic,retain) NSMutableString *str1;
@property (nonatomic,copy) NSMutableString *str2;

In the ".m" file.

NSMutableString *testRetain = [[NSMutableString alloc] initWithString:@"prefix"];
 NSLog(@"retain count is %d",[testRetain retainCount]);
 NSLog(@"mem add is %p",testRetain);

 str1 = testRetain;
 NSLog(@"retain count is %d",[testRetain retainCount]); 
 NSLog(@"mem add is %p",testRetain);

 str2 = testRetain;
 NSLog(@"retain count is %d",[str2 retainCount]); 
 NSLog(@"mem add is %p",str2);

all the retainCount and memory address are same. As I know, @property (nonatomic,retain) will add the retainCount of the object which be pointed.So the second part of code should output the same memory address and the different containCount from first part of code. and @property (nonatomic,copy) will copy the object to a new area.So the third part of code should output the dif开发者_如何学Cferent memory address from first part of code. Why i got this result. Thanks a lot.


Two points. First, and most important: don't use retainCount as a debugging tool. There are many reasons why it might not give you the value you're expecting. It says as much in the documentation.

But in this case -- point two -- the reason it's not working is that you're accessing the variables directly rather than using the accessors.

Instead of:

str = testRetain;

Try:

self.str = testRetain;


By using "str1" instead of "self.str1" you're not going through your (presumably synthesized) accessor methods for the property, so the memory management they do isn't happening.

As an additional note, you should be very wary of using the -retainCount method. Cocoa Touch will often do very strange things with the retain count (retaining, releasing, and autoreleasing internally, storing "special" retain counts for constant objects, etc...) that make it difficult-to-impossible to use effectively.

Rather than using the retain count, I suggest thinking of incrementing the retain count (by -copy, -alloc, -retain, +new, or -mutableCopy) as "claiming ownership of the object" and decrementing it (by -release or -autorelease) as "giving up ownership of the object". So as long as you always own each object you're using, and give them up when you're done with them, you should avoid both leaks and crashes.


What you should use is actually code like this:

self.str1 = ...;

Only in this way the setter method will be called.

By coding like this:

str1 = ...;

You are actually accessing the instance variable directly without calling the setter method, therefore no retain/copy happened.


str1 = testRetain; is setting the ivar directly to the same memory address. To use the accessors you have to use

self.str1 = testRetain;
self.str2 = testRetain;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜