Yanıtlar:
Referans türlerinde her zaman olduğu gibi, iki "kopya" kavramı vardır. Eminim onları biliyorsunuzdur, ama bütünlük açısından.
İkincisini istiyorsun. Bu kendi nesnelerinizden biriyse, NSCopying protokolünü benimsemeniz ve - (id) copyWithZone: (NSZone *) bölgesini uygulamanız yeterlidir. Ne istersen yapmakta özgürsün; Ancak fikir, kendinizin gerçek bir kopyasını yapıp geri vermenizdir. Derin bir kopya oluşturmak için tüm alanlarınızda copyWithZone'u çağırırsınız. Basit bir örnek
@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
, yoksa burada bir şey mi özlüyorum?
copyWithZone:
bu kriteri karşıladığından, tutma sayısı +1 olan bir nesne döndürmelidir.
alloc
yerine kullanmak için bir neden var mı allocWithZone:
?
allocWithZone
.
Apple belgeleri diyor
CopyWithZone: yönteminin bir alt sınıf sürümü, alt sınıf doğrudan NSObject'ten gelmedikçe, uygulamasını dahil etmek için mesajı süper'e göndermelidir.
mevcut cevaba eklemek için
@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:'
. Sanırım bu sadece uygulayan başka bir özel sınıftan miras alırken gerekliydicopyWithZone
Bu kodla benimki arasındaki farkı bilmiyorum, ancak bu çözümle ilgili sorunlarım var, bu yüzden biraz daha okudum ve nesneyi iade etmeden önce ayarlamamız gerektiğini gördüm. Şöyle bir şey demek istiyorum:
#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;
}
Bu yanıtı ekledim çünkü bu sorunla ilgili çok sorunum var ve neden olduğu konusunda hiçbir fikrim yok. Farkı bilmiyorum ama benim için çalışıyor ve belki başkaları için de faydalı olabilir :)
another.obj = [obj copyWithZone: zone];
Sanırım, bu satır bellek sızıntısına neden oluyor, çünkü obj
(sanırım) olarak ilan edilen özelliğe erişiyorsunuz retain
. Yani, alıkoyma sayısı mülkiyet tarafından artırılacak ve copyWithZone
.
Bunun olması gerektiğine inanıyorum:
another.obj = [[obj copyWithZone: zone] autorelease];
veya:
SomeOtherObject *temp = [obj copyWithZone: zone];
another.obj = temp;
[temp release];
Kopyalama için -> operatörünün kullanımı da vardır. Örneğin:
-(id)copyWithZone:(NSZone*)zone
{
MYClass* copy = [MYClass new];
copy->_property1 = self->_property1;
...
copy->_propertyN = self->_propertyN;
return copy;
}
Buradaki mantık, kopyalanan nesnenin orijinal nesnenin durumunu yansıtması gerektiğidir. "." Bu, alıcıları aradığından operatör yan etkiler getirebilir ve bu da mantık içerebilir.