【问题标题】:NSString no 'assign', 'retain', or 'copy' attribute is specifiedNSString 没有指定“assign”、“retain”或“copy”属性
【发布时间】:2009-11-02 18:07:31
【问题描述】:

我在一个类中声明一个 NSString 属性,而objective-c 抱怨:

NSString 没有指定“assign”、“retain”或“copy”属性

然后它随便让我知道“使用了assign”。

谁能解释一下assignretaincopy普通C内存管理方面的区别 功能?

【问题讨论】:

    标签: objective-c memory-management nsstring


    【解决方案1】:

    我认为这会引起您的注意,即使用assign,而不是retaincopy。由于NSString 是一个对象,因此在引用计数环境(即没有垃圾收集)中,这可能是“危险的”(除非它是有意设计的)。

    但是assignretaincopy的区别如下:

    • assign:在属性的 setter 方法中,将实例变量简单地分配给新值,例如:

      - (void)setString:(NSString*)newString
      {
          string = newString;
      }
      

      这可能会导致问题,因为 Objective-C 对象使用引用计数,因此如果不保留对象,则有可能在您仍在使用字符串时释放字符串。

    • retain:这保留 setter 方法中的新值。例如:

      - (void)setString:(NSString*)newString
      {
          [newString retain];
          [string release];
          string = newString;
      }
      

      这样更安全,因为您明确声明要维护对象的引用,并且必须在释放它之前释放它。

    • copy:这会在您的 setter 方法中复制字符串:

      - (void)setString:(NSString*)newString
      {
          if(string!=newString)
          {
              [string release];
              string = [newString copy];
          }
      }
      

      这通常与字符串一起使用,因为制作原始对象的副本可确保在您使用它时不会更改它。

    【讨论】:

      【解决方案2】:

      Cocoa 使用引用计数来管理内存。引用计数为 0 的对象将被删除。

      • assign - 对引用计数没有任何作用,只是将变量指向数据
      • retain - 将您的变量指向数据并将引用计数加 1,当您的变量仍然存在时,数据保证在那里
      • copy - 复制数据,将变量指向它并使保留计数为 1

      更多详情here,在 Apple 自己的文档中。

      【讨论】:

      • 保留 - 即使 有人 [ deallocs ] 你引用的 NSString?还是只有在同一个实例的每个用户 [releases] 时才有效?
      • @bobobobo - 你应该永远自己打电话给dealloc。您应该始终使用releaseautorelease
      • 戴夫说了什么。保证您的数据的原因是因为您假设其他人只使用发布,仅通过他们的引用来降低引用计数。如果其他人或您自己通过 dealloc 或过度释放对象(从而不遵守规则),您的数据将无法得到保证!
      【解决方案3】:

      assign - 通过简单的赋值设置 ivar。实施:

      - (void) setFoo:(NSString *)newFoo {
        foo = newFoo;
      }
      

      retain - 在分配之前向 ivar 发送保留消息。实施:

      - (void) setFoo:(NSString *)newFoo {
        if (foo != newFoo) {
          [foo release];
          foo = [newFoo retain];
        }
      }
      

      copy - 在执行分配之前向 ivar 发送复制消息。实施:

      - (void) setFoo:(NSString *)newFoo {
        if (foo != newFoo) {
          [foo release];
          foo = [newFoo copy];
        }
      }
      

      【讨论】:

      • 这些不是编译器@synthesizes 的实际实现,而是从(非GC)内存管理的角度展示行为。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-26
      • 2018-12-17
      • 2020-07-29
      • 2015-08-01
      • 2013-06-13
      • 2021-03-19
      • 1970-01-01
      相关资源
      最近更新 更多