我在一个类中声明一个NSString属性,而objective-c抱怨:
NSString没有指定'assign','retain'或'copy'属性
然后随便让我知道“使用”分配“。
根据正常的C内存管理分配,保留和复制之间的区别>功能?
答案 0 :(得分:30)
我认为它引起了您注意使用assign
这一事实,而不是retain
或copy
。由于NSString
是一个对象,在引用计数环境中(即没有垃圾收集),这可能是“危险的”(除非是故意设计)。
但是,assign
,retain
和copy
之间的区别如下:
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的对象将被删除。
更多细节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];
}
}