[英]How to copy an object in Objective-C
我需要深度復制一個具有自己對象的自定義對象。 我一直在閱讀,對於如何繼承 NSCopying 以及如何使用 NSCopyObject 感到有些困惑。
與引用類型一樣,“復制”有兩個概念。 我相信你知道他們,但為了完整性。
你想要后者。 如果這是您自己的對象之一,您只需采用 NSCopying 協議並實現 -(id)copyWithZone:(NSZone *)zone。 你可以隨心所欲; 雖然這個想法是你制作自己的真實副本並將其歸還。 您在所有字段上調用 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;
}
蘋果文檔說
copyWithZone: 方法的子類版本應該首先將消息發送到 super,以合並其實現,除非子類直接從 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;
}
我不知道那個代碼和我的有什么區別,但是我對那個解決方案有問題,所以我讀了一點,發現我們必須在返回之前設置對象。 我的意思是這樣的:
#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;
}
我添加了這個答案是因為我在這個問題上有很多問題,我不知道為什么會這樣。 我不知道有什么區別,但它對我有用,也許對其他人也有用:)
another.obj = [obj copyWithZone: zone];
我認為,這一行會導致內存泄漏,因為您可以通過(我假設)聲明為retain
屬性訪問obj
。 因此,保留計數將通過 property 和copyWithZone
增加。
我認為應該是:
another.obj = [[obj copyWithZone: zone] autorelease];
要么:
SomeOtherObject *temp = [obj copyWithZone: zone];
another.obj = temp;
[temp release];
還可以使用 -> 運算符進行復制。 例如:
-(id)copyWithZone:(NSZone*)zone
{
MYClass* copy = [MYClass new];
copy->_property1 = self->_property1;
...
copy->_propertyN = self->_propertyN;
return copy;
}
這里的推理是生成的復制對象應該反映原始對象的狀態。 這 ”。” 運算符可能會引入副作用,因為這會調用 getter,而 getter 又可能包含邏輯。
這可能是不受歡迎的方式。 但在這里我是如何做到的:
object1 = // object to copy
YourClass *object2 = [[YourClass alloc] init];
object2.property1 = object1.property1;
object2.property2 = object1.property2;
..
etc.
非常簡單直接。 :P
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.