.net - Cocoa Core Data 新手指南

标签 .net cocoa core-data cocoa-bindings

我是一大批热衷于尝试 Mac OS X 开发的未经洗礼的 .NET 开发人员之一。目前我正在尝试弄清楚 Cocoa 的各种元素,但在核心数据上有点卡住了。

我注意到 Web 上提供的大多数文档和资源都涉及广泛的端到端教程,从模型、生成类、基于文档的 UI 等开始。似乎没有足够多的关注每一点,或者至少没有足够的例子。

有人可以为我指明正确的方向吗?无论是在线 Material 还是书籍,都可以为我提供各个方面的详细说明?也许我陷入了.NET世界,但我仍然在数据访问层等方面思考。我想了解“CRUD”的基础知识,例如设置持久存储、创建实体、编辑、保存存储等。只是基础知识,不详细说明 UI。如果我可以对各个部分进行单元测试,那就太好了。

我想我正在尝试进入正确的心态 - .NET 开发人员是否知道适合像我们这样研究 Cocoa 编程的人的阅读 Material ?

非常感谢, 丹妮。

最佳答案

首先,正如 Apple 文档(以及 Apple 工程师反复评论)所述,Core Data 是一项“高级”Cocoa 技术。 Grokking Core Data 需要了解许多 Cocoa 范式和模式。说真的,先学习Cocoa。然后编写一个(或多个)没有 Core Data 的项目。然后学习核心数据。说真的。

为了平息你的好奇心,我将尝试一下 CRUD 答案,尽管这不会是你想要的答案。答案是 Core Data 没有 CRUD 模式,至少不是你想象的那样。原因是Core Data不是数据访问层。它是一个对象图管理框架。这意味着 Core Data 的明确预期工作是管理对象实例图。该图具有约束(例如关系的基数或对单个实例属性的约束)和通过该图进行级联更改(例如删除)的规则。核心数据管理这些约束。由于对象图可能太大而无法存储在内存中,因此 Core Data 为对象图提供了一个接口(interface),该接口(interface)通过故障模拟[1]内存中的整个对象图(当第一次将对象实例引入托管时,对象实例不是“故障”)对象上下文并被“触发”以延迟地从持久性存储中填充其属性)和唯一性(在上下文中仅创建特定实体实例(在持久性存储中)的一个内存中实例)。

Core Data 只是碰巧使用磁盘上的持久存储来实现大型对象图的接口(interface)。对于 SQLite 持久存储,此实现恰好使用 SQL 兼容的数据库。然而,这是一个实现细节。例如,您可以创建一个内存中持久存储,它不会将任何内容保存到磁盘,但允许 Core Data 像往常一样管理您的对象图。因此,Core Data 并不是真正的数据访问层。从这些角度来思考它会错过它的真正力量并会导致挫败感。您不能将 Core Data 与任意数据库模式一起使用(这就是为什么所有 Core Data 教程都从创建 NSManagedObjectModel 开始)。您不应该使用 Core Data 作为持久性框架并使用单独的模型层;您应该使用 Core Data 作为模型层,并利用 Core Data 的能力将模型的对象图保存到磁盘。

也就是说,要创建一个 NSManagedObjectContext (它提供了我上面描述的对象图接口(interface)):

NSManagedObjectModel *mom = [NSManagedObjectModel mergedModelFromBundles:[NSArray arrayWithObject:[NSBundle mainBundle]]]; // though you can create a model on the fly (i.e. in code)
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];

NSError *err;

// add an in-memory store. At least one persistent store is required
if([psc addPersistentStoreWithType:NSInMemoryPersistentStore configuration:nil URL:nil options:nil error:&err] == nil) {
  NSLog(@"%@",err);
}

NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
[moc setPersistentStoreCoordinator:psc];

(请注意,我假设您正在使用垃圾收集;此代码在手动内存管理环境中会泄漏)。

添加实体实例(继续上面的 moc):

NSEntityDescription *entity = [NSEntityDescription entityForName:@"MyEntity" inManagedObjectContext:moc];  
//entity will be nil if MyEntity doesn't exist in moc.persistentStoreCoordinator.managedObjectModel

NSManagedObject *obj = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:moc];

请注意,您需要实体描述来创建托管对象(为什么教程从模型开始),并且您无法在没有托管对象上下文的情况下创建托管对象。

更新实体实例:

[obj setValue:myValue forKey:@"attributeKey"]; //or use any method on `obj` that updates its state
NSError *err;
if(![moc save:&err]) {
  NSLog(@"%@", err); // an erro occurred in saving, perhaps due to optimistic locking failure
}

删除实体实例:

[moc deleteObject:obj];
if(![moc save:&err]) {
  NSLog(@"%@", err); // an erro occurred in saving, perhaps due to optimistic locking failure
}

[1]:对于二进制或 XML 持久存储,整个图存储在内存中

关于.net - Cocoa Core Data 新手指南,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1714054/

相关文章:

macos - 如何按宽度分割 NSAttributedString?

macos - 如何查找磁盘卷的格式

.net - MSBuild 编译错误 "resgen.exe".Net FX 3.5 工具

.net - 如何解决 .NET 中数据表的并发冲突?

macos - 哪个 NSTableView 接收 NSMenuItem?

ios - 如何在NSPredicate中使用NSDate和NSString从Core Data中获取数据?

ios - 如何以简单的方式备份没有搜索索引的 CoreData 存储 (SQLite)?

iphone - 核心数据自定义部分标题/索引

.net - 使用 Rijndael.Create() 而不是 new RijndaelManaged() 是否安全

c# - 是否可以选择一列的总和,按另一列分组?