回答:
参照型の場合と同様に、「コピー」には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;
}
autorelease
それをすべきではありませんか、それとも私はここで何か不足していますか?
copyWithZone:
この基準を満たすため、保持カウントが+1のオブジェクトを返す必要があります。
alloc
代わりに使用する理由はありallocWithZone:
ますか?
allocWithZone
。
アップルのドキュメントは言う
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;
}
No visible @interface for 'NSObject' declares the selector 'copyWithZone:'
。これは、実装する他のカスタムクラスから継承する場合にのみ必要だと思いますcopyWithZone
そのコードと私の違いはわかりませんが、その解決策には問題があるので、もう少し読んで、オブジェクトを返す前にオブジェクトを設定する必要があることがわかりました。私は次のようなものを意味します:
#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
。したがって、保持カウントはプロパティおよびによって増加します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;
}
ここでの推論は、結果のコピーされたオブジェクトが元のオブジェクトの状態を反映する必要があるためです。「。」演算子は、ロジックを含む可能性のあるゲッターを呼び出すため、副作用を引き起こす可能性があります。