Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在Swift领域从一对一关系到一对多关系_Ios_Swift_Realm - Fatal编程技术网

Ios 在Swift领域从一对一关系到一对多关系

Ios 在Swift领域从一对一关系到一对多关系,ios,swift,realm,Ios,Swift,Realm,我正在使用Swift 2.1.1和RealmSwift 0.97.1构建一个Swift iOS应用程序。我最初的需求涉及类a和B之间的一对一关系,因此我写了以下内容: class A: Object { dynamic var b: B? // A has one B } class B: Object { var a: A { return linkingObjects(A.self, forProperty: "b")[0] } } 这很有效,但现

我正在使用
Swift 2.1.1
RealmSwift 0.97.1
构建一个Swift iOS应用程序。我最初的需求涉及类
a
B
之间的一对一关系,因此我写了以下内容:

class A: Object {
    dynamic var b: B? // A has one B
}

class B: Object {
    var a: A {
        return linkingObjects(A.self, forProperty: "b")[0]
    }
}
这很有效,但现在我的需求发生了变化,我需要一对多关系:

class A: Object {
    var bs: [B] {
        return linkingObjects(B.self, forProperty: "a")
    }
}

class B: Object {
    dynamic var a: A? // B belongs to A
}
for (aKey, bKey) in keyMap {
    let a = realm.objectForPrimaryKey(A.self, key: aKey)
    let b = realm.objectForPrimaryKey(B.self, key: bKey)

    b?.a = a
    a?.b = nil
}
我有拥有真实数据的用户,所以我真的很想通过迁移优雅地推进这一变化

根据我的尝试,不可能在迁移中更改关系(我得到
无法添加来自不同领域的对象
)。事实是否如此

作为一种解决方法,我创建了一个将a主键映射到B主键的字典。这也意味着我必须为B添加一个以前没有的主键。然后,在迁移之外,我更改了关系的顺序:

class A: Object {
    var bs: [B] {
        return linkingObjects(B.self, forProperty: "a")
    }
}

class B: Object {
    dynamic var a: A? // B belongs to A
}
for (aKey, bKey) in keyMap {
    let a = realm.objectForPrimaryKey(A.self, key: aKey)
    let b = realm.objectForPrimaryKey(B.self, key: bKey)

    b?.a = a
    a?.b = nil
}
这是可行的,但我似乎无法摆脱
A
b
属性。如果我试图删除它,构建字典的迁移部分就会失败:如果我使用
newObject
,则
A
s和
B
s之间没有链接;如果我使用
oldObject
,则
B
没有主键。如果我能对更新进行排序(首先添加主键,然后构建字典,然后删除
b
属性),这一切都会很好,但我认为这是不可能的


有没有更好的方法来实现这一改变?如果没有,是否有办法删除
b
属性?

如果所有
b
对象都由一个
a
对象链接,则可以在迁移过程中执行以下操作:

migration.deleteData("B")
migration.enumerate("A") { oldObject, newObject in
    let b = migration.create("B", value: oldObject!["b"]!)
    (newObject!["bs"] as! List<MigrationObject>).append(b)
}
migration.deleteData(“B”)
枚举(“A”){oldObject,newObject in
让b=migration.create(“b”,值:oldObject![“b”]!)
(newObject![“bs”]as!List)。追加(b)
}

这是因为,如果不保留属性
b
,而不是删除所有现有的
b
对象,而是链接到它们的新副本,则无法获得与
newObject
兼容的链接对象的引用。

如果您采用相反的方式,将不会更容易。表示离开
B
有链接到
bs
A
列表
class A:Object{let bs=List()}class B:Object{var A:A{return linkingObjects(A.self,forProperty:“bs”)}
然后您可以将
oldObject[“B”]
附加到
newObject[“bs”]
@Ismail-乍一看,我想删除
b
属性也会遇到类似的问题,但这是个好主意。当我做类似于
让bs=newObject?[“bs”]as这样的事情时,我会完成它并报告?List
bs?.append((oldObject?[“b”])!as!MigrationObject)
在迁移过程中,我发现错误
对象已保存在域中
。因此,要使这种解决方案起作用,我还需要保存主键并在迁移之外更改关系,这意味着我不能删除
b
属性。