Ich versuche ein paar Dinge in meinem Kopf über die Implementierung zu klären copyWithZone:
, kann jemand Folgendes kommentieren ...
// 001: Crime is a subclass of NSObject.
- (id)copyWithZone:(NSZone *)zone {
Crime *newCrime = [[[self class] allocWithZone:zone] init];
if(newCrime) {
[newCrime setMonth:[self month]];
[newCrime setCategory:[self category]];
[newCrime setCoordinate:[self coordinate]];
[newCrime setLocationName:[self locationName]];
[newCrime setTitle:[self title]];
[newCrime setSubtitle:[self subtitle]];
}
return newCrime;
}
// 002: Crime is not a subclass of NSObject.
- (id)copyWithZone:(NSZone *)zone {
Crime *newCrime = [super copyWithZone:zone];
[newCrime setMonth:[self month]];
[newCrime setCategory:[self category]];
[newCrime setCoordinate:[self coordinate]];
[newCrime setLocationName:[self locationName]];
[newCrime setTitle:[self title]];
[newCrime setSubtitle:[self subtitle]];
return newCrime;
}
In 001:
Ist es am besten, den Klassennamen direkt zu schreiben
[[Crime allocWithZone:zone] init]
oder sollte ich verwenden[[[self Class] allocWithZone:zone] init]
?Ist es in
[self month]
Ordnung, die iVars zu kopieren, oder sollte ich direkt auf die iVars zugreifen, dh_month
?
quelle
NSCopying
. Zum BeispielNSObject
nicht, so dass ein Aufruf[super copyWithZone: zone]
eine Ausnahme auslöst.[super copyWithZone:zone]
wenn die übergeordnete Klasse NSCopying unterstützt. Andernfalls sollten Sie[[[self class] allocWithZone:zone] init]
Felder nach Bedarf aufrufen und kopieren.Das Standardkopierverhalten der
copyWithZone:
Methode mit von SDK bereitgestellten Objekten ist "flache Kopie". Das heißt, wenn SiecopyWithZone:
einNSString
Objekt aufrufen , wird eine flache, aber keine tiefe Kopie erstellt. Der Unterschied zwischen flacher und tiefer Kopie ist:Eine flache Kopie eines Objekts kopiert nur die Verweise auf die Objekte des ursprünglichen Arrays und platziert sie im neuen Array.
Eine tiefe Kopie kopiert tatsächlich die einzelnen im Objekt enthaltenen Objekte. Dazu senden Sie jedem einzelnen Objekt die
copyWithZone:
Nachricht in Ihrer benutzerdefinierten Klassenmethode.INSHORT: Um eine flache Kopie zu erhalten, rufen Sie
retain
oderstrong
alle Instanzvariablen auf. Um eine tiefe Kopie zu erhalten, rufen SiecopyWithZone:
alle Instanzvariablen in Ihrer benutzerdefinierten Klassenimplementierung aufcopyWithZone:
. Jetzt haben Sie die Wahl.quelle
Wie wäre es mit diesem, der Deep Copy implementiert:
/// Class Foo has two properties: month and category - (id)copyWithZone:(NSZone *zone) { Foo *newFoo; if ([self.superclass instancesRespondToSelector:@selector(copyWithZone:)]) { newFoo = [super copyWithZone:zone]; } else { newFoo = [[self.class allocWithZone:zone] init]; } newFoo->_month = [_month copyWithZone:zone]; newFoo->_category = [_category copyWithZone:zone]; return newFoo; }
quelle
Das ist mein Modell.
#import <Foundation/Foundation.h> @interface RSRFDAModel : NSObject @property (nonatomic, assign) NSInteger objectId; @property (nonatomic, copy) NSString *name; @property (nonatomic, strong) NSArray<RSRFDAModel *> *beans; @end #import "RSRFDAModel.h" @interface RSRFDAModel () <NSCopying> @end @implementation RSRFDAModel -(id)copyWithZone:(NSZone *)zone { RSRFDAModel *model = [[[self class] allocWithZone:zone] init]; model.objectId = self.objectId; model.name = self.name; model.beans = [self.beans mutableCopy]; return model; } @end
quelle