独自のオブジェクトを持つカスタムオブジェクトをディープコピーする必要があります。 NSCopyingを継承する方法とNSCopyObjectを使用する方法について、私は読んでいて少し混乱しています。
参照型と同様に、「コピー」には2つの概念があります。あなたはそれらを知っていると確信していますが、完全を期しています。
後者が必要です。これが独自のオブジェクトの1つである場合、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;
}
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;
}
私はそのコードと私のコードの違いを知りませんが、その解決策に問題があるので、もう少し読んで、返される前にオブジェクトを設定する必要があることがわかりました。私は次のようなものを意味します:
#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];
obj
として宣言されている(と仮定する)プロパティを介してretain
にアクセスするため、この行はメモリリークを引き起こすと思います。したがって、retain countは、プロパティおよび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;
}
ここでの理由は、コピーされたオブジェクトが元のオブジェクトの状態を反映する必要があるためです。 「。」演算子は、ロジックを含む可能性があるゲッターを呼び出すため、副作用を引き起こす可能性があります。