在过去的几个月里,我花费了大量的时间在研究 Core Data 之上,我得去处理一个使用了很多陈旧的代码,糟糕的 Core Data 以及违反了多线程安全的项目。讲真,Core Data 学习起来非常的困难,在学习 Core Data 的时候,你肯定会感到迷惑和一种深深的挫败感。正是因为这些原因,我决定给出一种超级简单的解决方案。这个方案的特点就是简洁,线程安全,非常易于使用,这个方案能满足你大部分对于 Core Data 的需求。在经过若干次的迭代后,我所设计的方案最终成为一个成熟的方案。
self.skiathos = [Skiathos setupInMemoryStackWithDataModelFileName:@"<#datamodelfilename>"]; // or self.skiathos = [Skiathos setupSqliteStackWithDataModelFileName:@"<#datamodelfilename>"];
在使用 Skopelos 时,代码如下所示:
1 2 3
self.skopelos =SkopelosClient(inMemoryStack: "<#datamodelfilename>") // or self.skopelos =SkopelosClient(sqliteStack: "<#datamodelfilename>")
你可以通过使用依赖注入的方式来在应用的其余地方使用这些对象。不得不说,为 Core Data 栈上的不同对象创建单例是一种很不错的做法。当然,不断的创建实例的开销是十分巨大的。通常来讲,我们不是很推荐使用单例模式。单例模式的测试性不强,在使用过程中,使用者无法有效的控制其声明周期,这样可能会违背一些最佳实践的编程原则。正是因为如此,在这个库里,我们不推荐使用单例。
@interfaceSkiathosClient : Skiathos + (SkiathosClient*)sharedInstance; @end staticSkiathosClient*sharedInstance =nil; @implementationSkiathosClient + (SkiathosClient*)sharedInstance { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedInstance = [self setupSqliteStackWithDataModelFileName:@"<#datamodelfilename>"]; </#datamodelfilename> }); return sharedInstance; } - (void)handleError:(NSError*)error { // clients should do the right thing here NSLog(@"%@", error.description); } @end
或者是
1 2 3 4 5 6 7
classSkopelosClient: Skopelos { staticlet sharedInstance =Skopelos(sqliteStack: "DataModel") overridefunchandleError(error: NSError) { // clients should do the right thing here print(error.description) } }
NSManagedObjectContext *context = ...; [context performBlockAndWait:^{ User *user = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass(User) inManagedObjectContext:context]; user.firstname = @"John"; user.lastname = @"Doe"; NSError *error; [context save:&error]; if (!error) { // continue to save back to the store } }];
// Sync SkopelosClient.sharedInstance.writeSync { context in let user =User.SK_create(context) user.firstname ="John" user.lastname ="Doe" } SkopelosClient.sharedInstance.writeSync({ context in let user =User.SK_create(context) user.firstname ="John" user.lastname ="Doe" }, completion: { (error: NSError?) in // changes are saved to the persistent store }) // Async SkopelosClient.sharedInstance.writeAsync { context in let user =User.SK_create(context) user.firstname ="John" user.lastname ="Doe" } SkopelosClient.sharedInstance.writeAsync({ context in let user =User.SK_create(context) user.firstname ="John" user.lastname ="Doe" }, completion: { (error: NSError?) in // changes are saved to the persistent store })
链式调用:
1 2 3 4 5 6 7 8 9 10 11 12
SkopelosClient.sharedInstance.write { context in user =User.SK_create(context) user.firstname ="John" user.lastname ="Doe" }.write { context in iflet userInContext = user.SK_inContext(context) { userInContext.SK_remove(context) } }.read { context in let users =User.SK_all(context) print(users) }