总结一下我所做的事情:
创建了一个名为 2048 的项目。
创建了 NSManagedObject 的子类
class BestScore: NSManagedObject { @NSManaged var bestScoreModel: BestScoreModel func update(score: Int) { self.bestScoreModel!.score = score } }
创建了 NSManagedObjectModel 的子类
class BestScoreModel: NSManagedObjectModel { @NSManaged var score: Int }
在“核心数据”选项卡下创建了一个数据模型。将该文件命名为 2048.xcdatamodeld。添加了一个实体BestScoreModel,其属性为“score”,并将类型定义为Integer 16。此外,我还根据official document将实体的类更新为2048.BestScoreModel。 .
在 Controller 类中,我添加了以下变量
class HomeViewController: UIViewController { var bestScore: BestScore? @lazy var context: NSManagedObjectContext = { let serviceName = NSBundle.mainBundle().infoDictionary.objectForKey("CFBundleName") as String let modelURL = NSBundle.mainBundle().URLForResource(serviceName, withExtension: "momd") let model = NSManagedObjectModel(contentsOfURL: modelURL) if model == nil { println("Error initilizing model from : \(modelURL)") abort() } let coordinator = NSPersistentStoreCoordinator(managedObjectModel: model) let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask) let storeURL = (urls[urls.endIndex-1]).URLByAppendingPathComponent("\(serviceName).sqlite") var error: NSError? = nil var store = coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil, error: &error) if store == nil { println("Failed to load store at \(storeURL) with error: \(error?.localizedDescription)") abort() } var context = NSManagedObjectContext() context.persistentStoreCoordinator = coordinator return context }() override func viewDidLoad() { super.viewDidLoad() let entity: NSEntityDescription = NSEntityDescription.entityForName("BestScoreModel", inManagedObjectContext: context) bestScore = BestScore(entity: entity, insertIntoManagedObjectContext: context) bestScore.update(0) } }
应用程序已成功构建,但当我运行模拟器时,它抛出以下异常
2014-07-13 00:56:59.944 2048[76600:4447122] -[NSManagedObject update:]: unrecognized selector sent to instance 0x10bc55d20
2014-07-13 00:56:59.948 2048[76600:4447122] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSManagedObject update:]: unrecognized selector sent to instance 0x10bc55d20'
我对 iOS 开发完全陌生,之前没有任何经验。我想以 Swift 为契机,在不学习 Objective-C 的情况下开始编写应用程序。如果我配置错误,请告诉我。
感谢您的帮助。
PS:我从 here 获取托管对象上下文的实现。非常感谢作者!
最佳答案
NSManagedObjectModel
描述了应用程序中使用的所有实体的集合,通常没有理由对其进行子类化。
我建议您对实体和相应的实体使用相同的名称 管理对象的子类。 (这也是 Xcode 在创建 Objective-C 托管对象子类时所做的事情)
Swift 托管对象子类(Xcode 尚无法自动创建) 看起来就像这样:
class BestScore: NSManagedObject {
@NSManaged var score: NSNumber
}
我使用了 NSNumber
类型而不是 Int16
,因为 Swift 中的标量访问器方法是托管的
对象子类尚未正常工作,比较 How to use Core Data Integer 64 with Swift Int64? .
然后将创建一个新的 BestScore 对象
bestScore = NSEntityDescription.insertNewObjectForEntityForName("BestScore", inManagedObjectContext: context) as BestScore
您可以直接访问其属性,而不需要 update()
函数:
bestScore!.score = 0
其他备注:将 bestScore
属性定义为
隐式解包可选,因为您希望它在之后有一个值
viewDidLoad:
。这可以节省您以后的许多显式展开操作:
var bestScore: BestScore!
此外,如果应用程序第二次运行,您可能需要重新加载 现有的最佳分数,而不是创建一个新的对象。 这意味着您必须先执行获取请求,然后插入新的 仅当未找到时才对象:
let request = NSFetchRequest(entityName: "BestScore")
var error : NSError?
let result = context.executeFetchRequest(request, error: &error)
if !result || result.count == 0 {
// Error or no object found: create new one:
bestScore = NSEntityDescription.insertNewObjectForEntityForName("BestScore", inManagedObjectContext: context) as BestScore
bestScore.score = 0
} else {
// Use existing object:
bestScore = result[0] as BestScore
}
let score = bestScore.score.integerValue // NSNumber --> Integer
关于core-data - ManagedObjectModel 子类在 Swift 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24720855/