为什么我不能将结构数组保存到coredata中?

时间:2015-07-29 06:20:46

标签: swift core-data

我试图将一系列结构保存到coredata中。

class Model: NSManagedObject
{

 @NSManaged var decks:[astruct]  //Error here
}

和结构

struct astruct
{
let card:Card
var status:Bool
}


enum Card:Int
{
    ..
}

错误状态:属性无法标记为@NSMAnaged,因为其类型无法在obj-c中表示

2 个答案:

答案 0 :(得分:0)

高层的CoreData只是轻量级关系数据库的包装。与所有关系数据库一样,您受限于可以存储哪些数据类型。从xcdatamodeld文件中,您可以在Xcode中选择它,这是一个示例实体,其示例属性具有受支持的类型:

CoreData entity attribute data types

在屏幕快照中,您可以看到,与其他关系数据库一样,CoreData中没有数组数据类型。您应该像其他关系数据库一样使用CoreData。如果您的应用程序中有复杂的数据结构需要存储/检索,则需要计划如何分解并将应用程序数据结构转换为兼容的关系数据库实体/属性。有多种方法可以解决该问题,但是我从这里开始将数组视为数据库中的实体/表,并将数组的元素视为该实体/表中的行。 Decks CoreData实体应具有card属性作为整数类型之一,以映射回您的astruct.card枚举属性,并具有status属性作为布尔值,以映射至您的{{1} }属性。

注意:如果采用这种方法,则CoreData布尔类型与ObjC BOOL类型不兼容。 CoreData在后台使用布尔类型作为NSNumber,因此您的@NSManaged属性需要是NSNumber,而不是Swift的Bool类型。

答案 1 :(得分:-1)

根据您在托管对象模型中配置关系的方式,将多对多关系键入NSSetNSOrderedSet。这些集合或有序集合中包含的任何类型的对象也必须是NSManagedObject的子类,并且与托管对象模型中配置的关系相匹配。

我喜欢为NSSetNSOrderedSet创建一些通用函数,这些函数可以轻松地将它们映射到我想要的任何值的数组。

extension NSSet {
    func array<T>() -> [T] {
        var output = [T]()
        for obj in self.allObjects {
            if let t = obj as? T {
                output.append( t )
            }
        }
        return output
    }
}

extension NSOrderedSet {
    func array<T>() -> [T] {
        var output = [T]()
        for obj in self.array {
            if let t = obj as? T {
                output.append( t )
            }
        }
        return output
    }
}

所以在你的情况下,你会有这样的事情:

// Model declarations
@objc class Model: NSManagedObject {
    @NSManaged var decks: NSOrderedSet
}

@objc class Deck: NSManagedObject {
    @NSManaged var status: NSNumber // For bool
    @NSManaged var cards: NSOrderedSet
}

@objc class Card: NSManagedObject {}

// Sample usage
if let model = loadModel() {
    let decks: [Deck] = model.decks.array()
    for deck in decks {
        let cards: [Card] = deck.cards.array()
    }
}