【发布时间】:2009-11-02 18:07:31
【问题描述】:
我在一个类中声明一个 NSString 属性,而objective-c 抱怨:
NSString 没有指定“assign”、“retain”或“copy”属性
然后它随便让我知道“使用了assign”。
谁能解释一下assign、retain和copy在普通C内存管理方面的区别 功能?
【问题讨论】:
标签: objective-c memory-management nsstring
我在一个类中声明一个 NSString 属性,而objective-c 抱怨:
NSString 没有指定“assign”、“retain”或“copy”属性
然后它随便让我知道“使用了assign”。
谁能解释一下assign、retain和copy在普通C内存管理方面的区别 功能?
【问题讨论】:
标签: objective-c memory-management nsstring
我认为这会引起您的注意,即使用assign,而不是retain 或copy。由于NSString 是一个对象,因此在引用计数环境(即没有垃圾收集)中,这可能是“危险的”(除非它是有意设计的)。
但是assign、retain和copy的区别如下:
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];
}
}
这通常与字符串一起使用,因为制作原始对象的副本可确保在您使用它时不会更改它。
【讨论】:
Cocoa 使用引用计数来管理内存。引用计数为 0 的对象将被删除。
更多详情here,在 Apple 自己的文档中。
【讨论】:
dealloc。您应该始终使用release 或autorelease。
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];
}
}
【讨论】: