我需要深度复制具有自己对象的自定义对象。我一直在阅读,对于如何继承NSCopying以及如何使用NSCopyObject感到有点困惑。
答案 0 :(得分:187)
与参考类型一样,有两种“复制”概念。我相信你知道他们,但是为了完整。
你想要后者。如果这是您自己的对象之一,则只需采用协议NSCopying并实现 - (id)copyWithZone:(NSZone *)区域。你可以自由地做任何你想做的事情;虽然这个想法是你自己制作一个真实的副本并将其归还。您可以在所有字段上调用copyWithZone,以进行深层复制。一个简单的例子是
@interface YourClass : NSObject <NSCopying>
{
SomeOtherObject *obj;
}
// In the implementation
-(id)copyWithZone:(NSZone *)zone
{
// We'll ignore the zone for now
YourClass *another = [[YourClass alloc] init];
another.obj = [obj copyWithZone: zone];
return another;
}
答案 1 :(得分:23)
Apple文档说
copyWithZone:方法的子类版本应该发送消息 超级首先,要包含它的实现,除非是子类 直接从NSObject下载。
添加到现有答案
@interface YourClass : NSObject <NSCopying>
{
SomeOtherObject *obj;
}
// In the implementation
-(id)copyWithZone:(NSZone *)zone
{
YourClass *another = [super copyWithZone:zone];
another.obj = [obj copyWithZone: zone];
return another;
}
答案 2 :(得分:21)
我不知道该代码和我的代码之间的区别,但是我对该解决方案有疑问,所以我再读一点,发现我们必须在返回之前设置对象。我的意思是:
#import <Foundation/Foundation.h>
@interface YourObject : NSObject <NSCopying>
@property (strong, nonatomic) NSString *name;
@property (strong, nonatomic) NSString *line;
@property (strong, nonatomic) NSMutableString *tags;
@property (strong, nonatomic) NSString *htmlSource;
@property (strong, nonatomic) NSMutableString *obj;
-(id) copyWithZone: (NSZone *) zone;
@end
@implementation YourObject
-(id) copyWithZone: (NSZone *) zone
{
YourObject *copy = [[YourObject allocWithZone: zone] init];
[copy setNombre: self.name];
[copy setLinea: self.line];
[copy setTags: self.tags];
[copy setHtmlSource: self.htmlSource];
return copy;
}
我添加了这个答案,因为我在这个问题上遇到了很多问题,我不知道为什么会这样。我不知道区别,但它对我有用,也许它对其他人也有用:)
答案 3 :(得分:2)
another.obj = [obj copyWithZone: zone];
我认为,这一行导致内存泄漏,因为您通过属性({I})访问obj
声明为retain
。因此,保留计数将按属性和copyWithZone
增加。
我认为应该是:
another.obj = [[obj copyWithZone: zone] autorelease];
或:
SomeOtherObject *temp = [obj copyWithZone: zone];
another.obj = temp;
[temp release];
答案 4 :(得分:0)
还有使用 - &gt;复制操作员。例如:
-(id)copyWithZone:(NSZone*)zone
{
MYClass* copy = [MYClass new];
copy->_property1 = self->_property1;
...
copy->_propertyN = self->_propertyN;
return copy;
}
这里的推理是生成的复制对象应该反映原始对象的状态。 &#34;。&#34;运算符可以引入副作用,因为这会调用getter,而getter又可能包含逻辑。
答案 5 :(得分:0)
这可能是不受欢迎的方式。但是我该怎么做:
@Html.AntiForgeryToken()
非常简单直接。 :P