CoreData - дублировать существующий объект - PullRequest
2 голосов
/ 18 февраля 2012

Привет хотел бы дублировать объект из моей базы данных базы данных. Прямо сейчас я использую

        movement2 = [NSEntityDescription
                                     insertNewObjectForEntityForName:@"Movement" 
                                     inManagedObjectContext:self.managedObjectContext];

        movement2.name = movement.name;
        movement2.value = movement.value;
        movement2.date = movement.date;
        ... 

и это работает. но ...

Есть ли способ скопировать все значения от movement до movement2 в одну строку кода?

Ответы [ 3 ]

10 голосов
/ 19 февраля 2012

NSManagedObject, в отличие от NSObject, предоставляет API для перебора его атрибутов и связей.Или, скорее, это описание сущности.Это не однострочник.

movement2 = [NSEntityDescription insertNewObjectForEntityForName:@"Movement" 
                                          inManagedObjectContext:self.managedObjectContext];
NSEntityDescription *entity = [movement entity];
for (NSString *propertyName in [entity propertiesByName]) {
    [movement2 setValue:[movement valueForKey:propertyName] forKey:propertyName];
}

Подробнее см. в документации .

Этого будет достаточно для клонирования большинства объектов.Если структура базы данных правильная, то при этом копируются отношения, их обратные также будут обновлены.Таким образом, если ваше Движение было связано, скажем, с MovementDirection, а MovementDirection имеет обратное отношение 1-ко-многим parentMovements, этот набор parentMovements будет иметь как movement, так и movement2 внутри после вызова кодавыше.

1 голос
/ 26 марта 2018

Я сделал простейшее дублирующее расширение для NSManagedObject (на основе ответа @ coverback). Используйте с осторожностью (хотя для меня это работает до сих пор)

Swift 4:

enum CopyBehavior {
    case none, copy, deepcopy
}

extension NSManagedObject {
    func duplicate(only: [String]) -> NSManagedObject {
        return duplicate { only.contains($0) ? .copy : .none }
    }

    func duplicate(except: [String], deep: [String] = []) -> NSManagedObject {
        return duplicate { deep.contains($0) ? .deepcopy : except.contains($0) ? .none : .copy }
    }

    func duplicate(byProperties fun: (String) -> CopyBehavior) -> NSManagedObject {
        let duplicate = NSEntityDescription.insertNewObject(forEntityName: entity.name!, into: managedObjectContext!)

        for propertyName in entity.propertiesByName.keys {
            switch fun(propertyName) {
            case .copy:
                let value = self.value(forKey: propertyName)
                duplicate.setValue(value, forKey: propertyName)
            case .deepcopy:
                let value = self.value(forKey: propertyName)
                if let value = value as? NSSet {
                    let copy = value.map {
                        return ($0 as! NSManagedObject).duplicate(byProperties: fun)
                    }
                    duplicate.setValue(copy, forKey: propertyName)
                }
                else if let value = value as? NSOrderedSet {
                    let copy = value.map {
                        return ($0 as! NSManagedObject).duplicate(byProperties: fun)
                    }
                    duplicate.setValue(NSOrderedSet(array: copy), forKey: propertyName)
                }
                else if let value = value as? NSManagedObject {
                    let copy = value.duplicate(byProperties: fun)
                    duplicate.setValue(copy, forKey: propertyName)
                }
                else {
                    fatalError("Unrecognized deepcopy attribute!")
                }
            case .none:
                break
            }
        }

        return duplicate
    }
}
1 голос
/ 18 февраля 2012

В API нет способа скопировать NSManagedObjects, поскольку они не соответствуют ни NSCopying, ни NSCoding. Это имеет смысл, учитывая, что зачастую неясно, как бы вы хотели скопировать такой объект, если он имеет отношения: должен ли он иметь отношения к одним и тем же объектам или их копиям? Как насчет этих копий? Это сложные вопросы, ответы на которые, вероятно, зависят от характера отношений (ко многим или к одному) и, следовательно, от конкретных случаев использования базовых данных.

Итак, короткий ответ: я бы сделал то, что вы делаете в своем фрагменте, или, возможно, напишу метод для создания копии. Похоже, что ваши NSManagedObject s имеют только простые атрибуты и не имеют отношений, поэтому это должно быть просто.

...