NSString没有指定'assign','retain'或'copy'属性

时间:2009-11-02 18:07:32

标签: objective-c memory-management nsstring

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

  NSString没有指定'assign','retain'或'copy'属性

然后随便让我知道“使用”分配“。

根据正常的C内存管理分配保留复制之间的区别>功能?

3 个答案:

答案 0 :(得分:30)

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

但是,assignretaincopy之间的区别如下:

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

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

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

  • 保留:此保留您的setter方法中的新值。例如:

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

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

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

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

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

答案 1 :(得分:10)

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

  • assign - 无需引用计数只需将变量指向数据
  • 保留 - 将您的变量指向数据并将参考计数加1,保证数据在您的变量仍处于活动状态时存在
  • copy - 制作数据副本,将变量指向它并使保留计数为1

更多细节here,在Apple自己的文档中。

答案 2 :(得分: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];
  }
}