除了两级系统的核心功能外,mogenerator 还通过在您的机器头文件和实现文件中自动实施有关核心数据的许多最佳实践来帮助您。
属性访问器
访问实体属性的方法是 mogenerator 生成的核心。但是除了开箱即用的 Xcode 类生成器提供给您的访问器之外,还有一些不错的功能在访问器中实现。
标量访问器
Xcode 的内置生成器为您提供“对原始数据类型使用标量属性”的选项。此选项让您可以选择让 Xcode 创建属性,使用 NSTimeIntervals 而不是 NSDates 用于日期类型,BOOLs 而不是 NSNumbers 用于布尔类型,以及 int16_t(或类似)而不是 @ 987654330@s.
我觉得这很令人恼火,因为大多数时候我更喜欢原始类型,但不是NSDates,因为它比NSTimeInterval 有用得多。所以 Core Data 给了我对象的选择,在这种情况下,我会不断地拆箱并犯像if(myBooleanAttribute) 这样的愚蠢错误(总是YES,因为myBooleanAttribute 是NSNumber,而不是BOOL )。或者我可以有标量,但在这种情况下,我得到NSTimeIntervals,我总是必须转换为NSDates。或者我可以手动编辑所有生成的文件,给我想要的NSDates 和BOOLs 的组合。
另一方面,mogenerator 为您提供了两种选择。例如,您将获得一个myBooleanAttribute getter,它为您提供一个NSNumber(便于存储在NSArray 中)和一个myBooleanAttributeValue getter,它为您提供一个实际的BOOL。与整数和浮点数相同。 (Mogenerator 不生成 NSTimeInterval 访问器:仅生成 NSDates。)
类型化的可转换属性
如果您有一个可转换的属性,您可以在属性中设置一个特定的 UserInfo 键 (attributeValueClassName),该键将指定您的属性将返回/接受的类。 (它会正确地转发声明类等。)我发现这个记录的唯一地方是Verious。
相比之下,Xcode 代码生成器只会将这些可转换的属性键入为 id 类型。
验证声明
虽然 mogenerator 不会自动生成任何验证方法,但它会在机器 h 文件中包含正确的签名作为注释。这似乎很大程度上是出于历史原因,但这确实意味着如果您决定在人工文件实现中实现签名,则很容易复制和粘贴签名。 (我实际上不会取消注释该声明,因为您不应该直接调用验证。)
原始访问器
Core Data 已经为您提供了这些原始值的访问器,但由于某种原因,它没有将它们包含在其 Xcode 生成的标头中。让 mogenerator 将它们包含在其头文件中可以更轻松地访问原始值。
获取的属性
mogenerator 将为获取的属性生成访问器。据我所知,没有办法让 Xcode 生成器执行此操作。
辅助方法
自动生成 NSFetchedResultsController
如果您的实体中存在多对多关系,并且您将 --template-var frc=true 传递给 mogenerator,则 mogenerator 将自动生成一个方法来为与父对象关联的子对象创建获取请求。它甚至会自动生成一个唯一的缓存名称,并将所有内容隔离在 #if TARGET_OS_IPHONE 预处理器宏中。
即使这不符合您的特定需求,它也是如何扩展模板的一个很好的例子。
+fetchMyFetchRequest:moc_
如果您喜欢在模型中定义获取请求,这比硬编码字符串要好得多。
-MyEntitySet
Mogenerator 使用 KVC 的魔力为您提供一个NSMutableSet 代理来处理您的关系。
+实体名称
需要为NSFetchRequest 或其他Core Data 方法提供实体名称?使用这种将实体名称返回为NSString 的简单方法可以轻松避免硬编码字符串。
+insertInManagedObjectContext: 和 entityInManagedObjectContext:
另一种避免硬编码实体名称的方法是使用这些辅助方法。
类型化的对象 ID
您的每个标头和实现还包含一个MyEntityID 类。它们是空的接口和实现,只是 NSManagedObjectID 类的子类。此外,每个模型类都有一个名为 objectID 的辅助方法,它覆盖 NSManagedObject 中的标准 objectID 方法。辅助方法除了将超类的返回值转换为 MyEntityID 类型之外什么都不做。
最终结果:如果您不小心交换了来自不同实体的对象 ID,编译器会发现您的错误。
杂项
继承自定义超类
其中一个命令行选项是--base-class:,它允许您指定一个基类,所有生成的类都将从该基类继承。这是非常有用的,要么你可以有一个基类来定义方便的方法(给定 Core Data,你可能应该这样做),或者你可以使用现成的 Core Data 工具包,如 SSDDataKit(或两者兼而有之)。
包含
一个简单的小东西,但如果你指定一个 --includem 参数,mogenerator 将生成一个包含所有模型头文件的头文件。如果您想在 PCH 中包含所有标头或您包含的其他一些标准标头,则很方便。
所有属性、关系、获取属性的常量定义
结构的外部声明包含在标头中,该标头为您的实体中定义的每个属性和关系定义了NSString。这允许您定义谓词和其他参数,而无需将实体名称烘焙到字符串中。例如,
req.predicate = [NSPredicate predicateWithFormat:
@"(%K == YES) AND (%K <= %@)",MyObject.favorite, MyObject.availableDate, [NSDate date]];
(用于“命名空间”常量的这种类型的结构在 his blogMy Mike Ash 上进行了描述
用户信息键/值的常量定义
类似地,结构的外部声明在标头中定义,其中包括作为结构成员的键和作为值的值。即
NSLog(@"User info for key my key is %@",MyObjectInfo.mykey) //will log "myvalue"
备用模板
mogenerator 的一个有趣之处在于,在构建 mogenerator 时,它的作者(Wolf Rentzsch)基本上为 Xcode 生成的 xcdatamodel 文件构建了一个通用解析器和模板引擎。所以你不需要使用 mogenerator 模板。您可以为自己提供一个简单的命令行参数。 GitHub 网站上有很多user contributed templates。
事实上,您甚至不必使用 Core Data。许多贡献的模板允许您基于数据模型生成一系列普通的 NSObject 模型类。 (所谓的 PONSO:“普通的旧 nsobjects”)。想在 Xcode 中使用数据建模器,但想使用其他一些持久性机制? mogenerator 可以为您提供帮助。
您甚至根本不需要生成对象:another interesting submitted template 只是提供了两个不同模型版本的差异。