Jawaban:
Seperti biasa dengan jenis referensi, ada dua pengertian tentang "salinan". Saya yakin Anda tahu mereka, tapi untuk kelengkapan.
Anda menginginkan yang terakhir. Jika ini adalah salah satu objek Anda, Anda hanya perlu mengadopsi protokol NSCopying dan menerapkan - (id) copyWithZone: (NSZone *) zona. Anda bebas melakukan apa pun yang Anda inginkan; meskipun idenya adalah Anda membuat salinan asli dari diri Anda dan mengembalikannya. Anda memanggil copyWithZone di semua bidang Anda, untuk membuat salinan dalam. Contoh sederhananya adalah
@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
melakukannya, atau apakah saya melewatkan sesuatu di sini?
copyWithZone:
memenuhi kriteria ini, oleh karena itu harus mengembalikan objek dengan jumlah retensi +1.
alloc
daripada allocWithZone:
sejak zona itu dilewati?
allocWithZone
.
Dokumentasi Apple mengatakan
Versi subkelas dari metode copyWithZone: harus mengirim pesan ke super terlebih dahulu, untuk memasukkan implementasinya, kecuali jika subkelas diturunkan langsung dari NSObject.
untuk menambah jawaban yang ada
@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:'
. Saya kira ini hanya diperlukan ketika kita mewarisi dari beberapa kelas khusus lain yang mengimplementasikancopyWithZone
Saya tidak tahu perbedaan antara kode itu dan milik saya, tetapi saya memiliki masalah dengan solusi itu, jadi saya membaca lebih banyak dan menemukan bahwa kita harus mengatur objek sebelum mengembalikannya. Maksud saya sesuatu seperti:
#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;
}
Saya menambahkan jawaban ini karena saya memiliki banyak masalah dengan masalah ini dan saya tidak tahu mengapa itu terjadi. Saya tidak tahu perbedaannya, tetapi ini berhasil untuk saya dan mungkin juga berguna untuk orang lain :)
another.obj = [obj copyWithZone: zone];
Saya pikir, baris ini menyebabkan kebocoran memori, karena Anda mengakses obj
melalui properti yang (saya asumsikan) dinyatakan sebagai retain
. Jadi, jumlah retensi akan ditingkatkan berdasarkan properti dan copyWithZone
.
Saya percaya itu harus:
another.obj = [[obj copyWithZone: zone] autorelease];
atau:
SomeOtherObject *temp = [obj copyWithZone: zone];
another.obj = temp;
[temp release];
Ada juga penggunaan operator -> untuk menyalin. Sebagai contoh:
-(id)copyWithZone:(NSZone*)zone
{
MYClass* copy = [MYClass new];
copy->_property1 = self->_property1;
...
copy->_propertyN = self->_propertyN;
return copy;
}
Alasan di sini adalah objek yang disalin harus mencerminkan keadaan objek aslinya. The "." operator dapat memperkenalkan efek samping karena yang satu ini memanggil getter yang pada gilirannya mungkin berisi logika.