Dav*_*ren 17 cocoa core-data mogenerator
我一直在使用mogenerator一段时间,虽然在命令行选项上有一个合理的入门指南和Stack Exchange文章,但我还没有找到它提供的所有功能的良好指南. 简而言之:除了Core Data为您提供的类之外,Mogenerator实际生成了什么?
(坦率地说,我一直在标题/实现中找到一些令人惊喜的惊喜,我没有意识到它们在那里,我决定逐步完成生成器模板和代码并记录我在Stack Exchange Q&A中发现的内容.我很乐意但是,请参阅其他答案和修改.)
Dav*_*ren 38
除了两级系统的核心功能外,mogenerator还可以通过在机器标头和实现文件中自动实施有关Core Data的大量最佳实践来帮助您.
访问实体属性的方法是生成器生成的核心.但是,除了Xcode类生成器提供的开箱即用之外,访问器中还实现了一些不错的功能.
Xcode的内置生成器为您提供了"使用原始数据类型的标量属性"选项.此选项使您可以选择让Xcode创建属性,NSTimeInterval而不是NSDates代表日期类型,BOOLs代替NSNumbers代表布尔类型,和int16_t(或类似)而不是NSNumbers.
我发现这令人愤怒,因为大多数时候我更喜欢原始类型,但不是因为NSDates比a更有用NSTimeInterval.因此,核心数据给了我对象的选择,在这种情况下,我会不断地拆箱并制造愚蠢的错误if(myBooleanAttribute)(这总是YES因为myBooleanAttribute是NSNumber,而不是a BOOL).或者我可以有标量,但在那种情况下,我得到NSTimeInterval的是我将永远必须转换为NSDates.或者我可以手动编辑所有生成的文件,以便为我提供所需的NSDates和BOOLs组合.
另一方面,mogenerator为您提供两种选择.例如,你将获得一个myBooleanAttributegetter NSNumber(给你一个容易的存储NSArray)和一个myBooleanAttributeValuegetter给你一个实际的BOOL.与整数和浮点数相同.(Mogenerator不生成NSTimeInterval访问器:只有NSDates.)
如果您具有可转换属性,则可以在属性中设置特定的UserInfo键(attributeValueClassName),该键将指定您的属性将返回/接受的类.(并且它会正确地向前宣布课程等.)我发现这个文件的唯一地方是Verious.
相反,Xcode代码生成器只会将这些可转换属性键入为id类型.
虽然mogenerator不会自动生成任何验证方法,但它确实在机器h文件中包含正确的签名作为注释.这似乎主要是出于历史原因,但它确实意味着如果您决定在人类文件实现中实现它,则很容易复制和粘贴签名.(我实际上不会取消声明,因为你不应该直接调用验证.)
Core Data已经为您提供了原始值的这些访问器,但由于某些原因,它们不会在Xcode生成的头中包含它们.让mogenerator将它们包含在头文件中可以更容易地访问原始值.
mogenerator将为获取的属性生成访问器.据我所知,没有办法让Xcode生成器执行此操作.
如果您的实体中有多对多关系并且将--template-var frc = true传递给mogenerator,则mogenerator将自动生成一个方法,以便为与父对象关联的子对象创建获取请求.它甚至可以自动生成唯一的缓存名称,并隔离#if TARGET_OS_IPHONE预处理器宏中的所有内容.
即使这不符合您的特定需求,它也是如何扩展模板的一个很好的例子.
如果您想在模型中定义获取请求,那么检索它们比硬编码字符串要好得多.
Mogenerator利用KVC的魔力为您提供NSMutableSet代理关系.
需要为一个NSFetchRequest或其他Core Data方法提供实体名称吗?通过使用这个简单的方法来回避实体的名称,很容易避免使用硬编码字符串NSString.
避免硬编码实体名称的另一种方法是使用这些辅助方法.
您的每个标头和实现还包括一个MyEntityID类.它们是空接口和实现,只是子类的NSManagedObjectID类.此外,每个模型类都有一个名为objectID的辅助方法,它覆盖了标准的objectID方法NSManagedObject.辅助方法除了将超类的返回值强制转换为MyEntityID类型之外什么都不做.
最终结果:如果您不小心将对象ID与不同实体交换,编译器可以捕获您的错误.
其中一个命令行选项--base-class:允许您指定所有生成的类将从中继承的基类.这非常有用,要么您可以拥有一个基类来定义便捷方法(给定Core Data,您可能应该这样),或者您可以使用现成的Core Data工具包,如SSDataKit(或两者).
一个简单的小东西,但如果你指定一个--includem参数,mogenerator将生成一个包含所有模型头文件的头文件.如果您想在PCH中包含所有标题,或者包含其他一些标准标题,则非常方便.
标头中包含一个结构的extern声明,它NSString为您的Entity中定义的每个属性和关系定义.这允许您定义谓词和其他参数,而无需将实体名称烘焙到字符串中.例如,
req.predicate = [NSPredicate predicateWithFormat:
@"(%K == YES) AND (%K <= %@)",MyObject.favorite, MyObject.availableDate, [NSDate date]];
Run Code Online (Sandbox Code Playgroud)
(用于"命名空间"常量的这种结构在他的博客上描述了My Mike Ash
类似地,在头部中定义了结构的extern声明,其包括作为结构的成员的键,以及作为值的值.即
NSLog(@"User info for key my key is %@",MyObjectInfo.mykey) //will log "myvalue"
Run Code Online (Sandbox Code Playgroud)
关于mogenerator的一个有趣的事情是,在构建mogenerator时,它的作者(Wolf Rentzsch)基本上为Xcode生成的xcdatamodel文件构建了一个通用的解析器和模板引擎.因此您不需要使用mogenerator模板.您可以使用简单的命令行参数提供自己的参数.GitHub网站上有很多用户提供的模板.
实际上,您甚至不必使用Core Data.许多提供的模板允许您基于数据模型生成一系列普通的NSObject模型类.(所谓的PONSO:"普通的老对手").想在Xcode中使用数据建模器,还有其他一些持久性机制?发电机可以帮助你.
你甚至根本不需要生成对象:另一个有趣的提交模板 只提供了两个不同模型版本的差异.