【问题标题】:Question about retain and copy in Objective c关于Objective c中保留和复制的问题
【发布时间】:2011-01-11 09:37:09
【问题描述】:

这个问题让我有点困惑。 在“.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) 会将对象复制到一个新区域。所以第三部分代码应该输出与第一部分代码不同的内存地址。 为什么我得到这个结果。 非常感谢。

【问题讨论】:

  • 你得到了什么结果?
  • str1 = testRetain 将 ivar 直接设置为相同的内存地址。要使用访问器,您必须使用 self.str1 = testRetain; self.str2 = testRetain

标签: iphone objective-c cocoa copy retain


【解决方案1】:

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

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

代替:

str = testRetain;

试试:

self.str = testRetain;

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

      self.str1 = ...;
      

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

      通过这样的编码:

      str1 = ...;
      

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-04-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-03-19
          • 2011-10-24
          • 1970-01-01
          相关资源
          最近更新 更多