[英]How to make NSManagedObject NSString properties be with “copy” instead of “retain”?
[英]NSString @property, using copy instead of retain
我正在查看 Apple 的示例应用程序 EditableDetailView,并注意到在他们的一个控制器中,他们正在使用(非原子,副本)设置 NSString 属性的实例。 什么时候会使用副本而不是保留? 这样他们就可以在不影响现有数据的情况下制作唯一的副本吗?
是的,它可以在不影响现有数据的情况下制作唯一副本。 合成的 setter 基本上如下所示:
// For @synthesize(nonatomic, retain) foo:
- (void) setFoo(NSFoo *theFoo)
{
[theFoo retain]; // retain new value
[foo release]; // release old value, if any
foo = theFoo; // assign new value
}
// For @synthesize(nonatomic, copy) foo:
- (void) setFoo(NSFoo *theFoo)
{
NSFoo* newFoo = [theFoo copy]; // make copy
[foo release]; // release old value, if any
foo = newFoo; // assign new value
}
注意这里的操作顺序很重要——新值必须在旧值被释放之前保留/复制,以防自赋值。 如果您先释放然后将属性分配给自身,则可能会意外释放该值。 另请注意,如果旧值为nil
,则可以向其发送release
消息,因为明确允许向nil
object 发送消息并且什么也不做。
选择保留还是复制只是决定了对象的属性是否与您设置的值相同。 考虑以下代码:
// suppose the 'foo' property is declared 'retain' and the 'bar' property is
// declared 'copy'
NSFoo *foo = ...;
NSBar *bar = ...;
someObject.foo = foo;
someObject.bar = bar;
[foo changeInternalState]; // someObject.foo also changes, since it's the same object
[bar changeInternalState]; // someObject.bar does NOT change, since it's a copy
请记住,有一个 NS可变字符串。 能够改变其他一些 object 拥有的字符串的内容(例如,通过删除其一半的字符)会非常糟糕,特别是如果您没有意识到您正在影响另一个 object。 因此,最好让其他 object 自己制作副本。
你可能会说“好吧,我为什么不在分配字符串之前复制它呢?”。 也许 object 想要一个可变字符串,而你的字符串是不可变的。 如果必须先复制字符串,则必须在其文档或 header 中查找所需的字符串类型,然后(每次)进行正确的复制。 这样,您只需说other.string = myString
,它就会生成它想要的任何类型的副本——您不必担心它。
(出于某种原因,这篇文章出现在我试图回答的后续问题之上)回复:
你的意思是我必须在发布'foo'之前复制'foo' object?但是如果我在复制'foo'之前释放'foo'会有什么问题?因为它们是两个不同的object我不明白为什么释放一个影响另一个!!!!
大多数时候,你是对的。 事实上,如果它们是两个独立的对象,那就没关系了。 问题在于您可能将相同的 object 分配回自身。 如果你说
[myObject setFoo: moof];
[myObject setFoo: moof];
然后你第二次这样做,你会在复制之前释放 moof。 在此期间,如果 moof 的保留计数变为零,则可能会删除 moof,并且在接下来的步骤中您将没有任何内容可复制。 Foo 现在为零。
这有可能发生吗? 可能比你想象的要多。 例如,有时用户可能会点击两次“更新”按钮。
我希望这是可以理解和有帮助的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.