简体   繁体   中英

How to properly use generics in Swift to store different types of objects in a list in Realm?

I am having a problem of Realm throwing an error that states that my type 'Category' is not managed by Realm.

For context, a 'Category' can hold either a collection of type 'Mistakes' or 'Subjects'. A 'Subject' can also contain a collection of 'Category' containing a collection of 'Mistake'. Thus, I am using generics so that I do not have to create two separate data models to group these two data models.

class Category<O:Object>:Object{

//properties
@objc dynamic var categoryName:String = ""

//relationships
let ChildObjects = List<O>() //type of child object is to be set by the generic type; two possible types: subjects & mistakes

//mother objects
var Subjects = LinkingObjects(fromType: Subject.self, property: "MistakeCategories") //For Mistake Categories

}

I load the results of a category of subjects, using the following code:

var CategoryDatabase:Results<Category<Subject>>!

CategoryDatabase = R.objects(Category<Subject>.self)

I have also tried using the following code:

var CategoryDatabase:Results<Category<Subject>>!

CategoryDatabase = R.objects(Category.self)

Nonetheless, I am having the error below.

*** Terminating app due to uncaught exception 'RLMException', reason: 'Object type '_TtGC8Go_For_A8CategoryCSo16RealmSwiftObject_' not managed by the Realm'

I have tried to search the internet for possible solutions but they their problems aren't exactly the same as mine. Nonetheless, I found this which could be a possible answer as to why I am getting the error. However, the error and its cause is different.

This is my generic function that worked properly when storing different types of objects into Realm database:

let realm = try! Realm()

func createObject<T: Object>(_ object: T) {
     do {
         try realm.write {
             realm.add(object)
           }
        } catch {
             print(error)
           }
        }

This is not going to work

let ChildObjects = List<O>() //...two possible types: subjects & mistakes

Realm Collections (Result, List) are homogenous and can only store zero or more instances of one object type; eg you can't store different classes of Object in the same List object

Generics are great but when you're working with different (possibly unrelated) objects, subjects and mistakes, using a generic is probably the wrong approach because queries and the actually data will be quite different.

Keep your data separate

let subjects = List<SubjectClass>()

and

let mistakes = List<MistakeClass>()

of if there is some connection make it one class

class SubjectClass: Object {
    @objc dynamic var subject_name = ""
    @objc dynamic var is_mistake = false
}

of if a subject can have lots of mistakes

class SubjectClass: Object {
    @objc dynamic var subject_name = ""
    let allMyMistakes = List<MistakeClass<>
}

For some data modeling info, review this answer and then a fantasic answer from @DávidPásztor here

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