关于Objective c中retain和copy的问题

发布于 2024-10-11 09:04:40 字数 810 浏览 6 评论 0原文

这个问题让我有点困惑。 在“.h”文件中。

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

在“.m”文件中。

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);

所有的retainCount和内存地址都是相同的。 据我所知,@property(nonatomic,retain)会添加所指向的对象的retainCount。因此,代码的第二部分应该输出与第一部分代码相同的内存地址和不同的containCount。 并且@property(nonatomic,copy)会将对象复制到新区域。因此代码的第三部分应该输出与代码第一部分不同的内存地址。 为什么我得到这个结果。 多谢。

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 different memory address from first part of code.
Why i got this result.
Thanks a lot.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

留一抹残留的笑 2024-10-18 09:04:40

两点。首先,也是最重要的:不要使用retainCount作为调试工具。有很多原因可能导致它无法为您提供预期的价值。它在文档中说了这么多。

但在这种情况下——第二点——它不起作用的原因是您直接访问变量而不是使用访问器。

而不是:

str = testRetain;

尝试:

self.str = testRetain;

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;
这样的小城市 2024-10-18 09:04:40

通过使用“str1”而不是“self.str1”,您不会使用该属性的(可能是合成的)访问器方法,因此它们所做的内存管理不会发生。

作为补充说明,您应该非常谨慎地使用 -retainCount 方法。 Cocoa Touch 经常会对保留计数做一些非常奇怪的事情(内部保留、释放和自动释放,存储常量对象的“特殊”保留计数等......),这使得它很难有效地使用。

我建议不要使用保留计数,而是考虑增加保留计数(通过 -copy、-alloc、-retain、+new 或 -mutableCopy)作为“声明对象的所有权”并减少它(通过 -release 或 - autorelease)作为“放弃对象的所有权”。因此,只要您始终拥有正在使用的每个对象,并在使用完它们后放弃它们,就应该避免泄漏和崩溃。

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.

抱猫软卧 2024-10-18 09:04:40

你应该使用的实际上是这样的代码:

self.str1 = ...;

只有这样setter方法才会被调用。

通过这样的编码:

str1 = ...;

您实际上是直接访问实例变量,而不调用 setter 方法,因此没有发生保留/复制。

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.

慵挽 2024-10-18 09:04:40

str1 = testRetain; 将 ivar 直接设置为相同的内存地址。
要使用访问器,您必须使用

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

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文