简体   繁体   中英

NSCopying Protocol Not Working

I am trying to copy an object, and I've implemented the NSCopying protocol, which looks like this:

#MyActivity.h
@interface MyActivity : MyModel <NSCopying>
{
    NSInteger activityId;
    NSInteger userId;
    NSInteger checkinId;
    NSString *status;
    NSString *dateCreated;
    NSString *dateModified;
    NSString *dateStart;
    NSString *dateEnd;
    NSString *activityDescription;
    NSString *name;
    NSString *type;
    NSString *repeat;
    NSString *routineName;
    NSString *startTimezone;
    NSString *endTimezone;
    GUILocation *location;
}

@property NSInteger activityId;
@property NSInteger userId;
@property NSInteger checkinId;

@property (nonatomic, strong) NSString *status;
@property (nonatomic, strong) NSString *dateCreated;
@property (nonatomic, strong) NSString *dateModified;
@property (nonatomic, strong) NSString *dateStart;
@property (nonatomic, strong) NSString *dateEnd;
@property (nonatomic, strong) NSString *activityDescription;
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *type;
@property (nonatomic, strong) NSString *repeat;
@property (nonatomic, strong) NSString *routineName;
@property (nonatomic, strong) NSString *startTimezone;
@property (nonatomic, strong) NSString *endTimezone;

@property (nonatomic, strong) MyLocation *location;

-(id)copyWithZone:(NSZone *)zone;
...

This is what my implementation file looks like:

#MyActivity.m
...
-(id)copyWithZone:(NSZone *) zone
{
    GUIActivity* copyActivity        = [super copyWithZone:zone];
    copyActivity.activityId          = self.activityId;
    copyActivity.userId              = self.userId;
    copyActivity.checkinId           = self.checkinId;
    copyActivity.status              = self.status;
    copyActivity.dateCreated         = self.dateCreated;
    copyActivity.dateModified        = self.dateModified;
    copyActivity.dateStart           = self.dateStart;
    copyActivity.dateEnd             = self.dateEnd;
    copyActivity.activityDescription = self.activityDescription;
    copyActivity.name                = self.name;
    copyActivity.type                = self.type;
    copyActivity.repeat              = self.repeat;
    copyActivity.routineName         = self.routineName;
    copyActivity.startTimezone       = self.startTimezone;
    copyActivity.endTimezone         = self.endTimezone;
    copyActivity.location            = [self.location copyWithZone:zone];


    return copyActivity;
}
...

When I attempt to copy by implementing this method:

- (void)addActivity:(MyActivity *)activity
          toResults:(NSMutableArray *)results
           withDate:(NSDate *)date
{
    MyActivity *actNow     = [activity copy];
    actNow.dateStart       = [NSDate stringFromDate:date];
    [results addObject:actNow];
}

I am still getting the error:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[RLMAccessor_v0_MyActivity copyWithZone:]: unrecognized selector sent to instance 0x7fe5e0c2c0a0'

The class MyActivity is a subclass of RLMObject , so I'm not sure if that has anything to do with the issue. Can someone point me in the right direction?

Realm internally overrides the accessors for the properties it manages, so it's not possible to make it conform to NSCopying in the traditional sense.

If you want to perform a full deep copy on an RLMObject , the Realm-JSON library actually provides a way to do this :

- (instancetype)deepCopy {
    RLMObject *object = [[NSClassFromString(self.objectSchema.className) alloc] init];

    for (RLMProperty *property in self.objectSchema.properties) {

        if (property.type == RLMPropertyTypeArray) {
            RLMArray *thisArray = [self valueForKeyPath:property.name];
            RLMArray *newArray = [object valueForKeyPath:property.name];

            for (RLMObject *currentObject in thisArray) {
                [newArray addObject:[currentObject deepCopy]];
            }

        }
        else if (property.type == RLMPropertyTypeObject) {
            RLMObject *value = [self valueForKeyPath:property.name];
            [object setValue:[value deepCopy] forKeyPath:property.name];
        }
        else {
            id value = [self valueForKeyPath:property.name];
            [object setValue:value forKeyPath:property.name];
        }
    }

    return object;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM