如何将类型安全结构类型 Core Data 属性与 mogenerator 一起使用?
对于 NSKeyValueCoding 可以处理的结构类型的属性,我使用 Apple 文档中描述的 Core Data 访问器模式 此处。
例如,可以在 Core Data 模型中将 NSRange 结构指定为 Transformable 类型,然后可以通过在 NSManagedObject 子类中提供以下形式的访问器来避免客户端使用 NSValue 胡言乱语:
Interface:
@property(assign, nonatomic) NSRange range;
实现;
- (NSRange) range {
[self willAccessValueForKey:@"range"];
NSRange retVal = range;
[self didAccessValueForKey:@"range"];
return retVal;
}
- (void)setRange:(NSRange)aRange {
[self willChangeValueForKey:@"range"];
range = aRange;
[self didChangeValueForKey:@"range"];
}
然而,Mogenerator 生成的 NSManagedObject 子类将 Transformable 属性声明为 NSObject 属性,因此客户端需要获取/设置 NSValues。
使用 mogenerator 处理这种情况的最佳方法是什么,同时(1)保持简单的 Transformable 模式而不是弄乱瞬态支持属性,以及(2)避免对 Mogenerator 的“机器”类进行任何编辑?
For attributes of struct types that NSKeyValueCoding can handle, I use the Core Data accessor pattern described in Apple's docs here.
For example, an NSRange struct can be specified in the Core Data model as of type Transformable, then the NSValue rigmarole can be avoided for clients by providing accessors in an NSManagedObject subclass of the form:
Interface:
@property(assign, nonatomic) NSRange range;
Implementation;
- (NSRange) range {
[self willAccessValueForKey:@"range"];
NSRange retVal = range;
[self didAccessValueForKey:@"range"];
return retVal;
}
- (void)setRange:(NSRange)aRange {
[self willChangeValueForKey:@"range"];
range = aRange;
[self didChangeValueForKey:@"range"];
}
Mogenerator's generated NSManagedObject subclasses, however, declare Transformable attributes as NSObject properties, so clients need to get/set NSValues.
What's the best way to handle this situation with mogenerator, whilst (1) keeping with the simple Transformable pattern rather than messing with transient backing attributes, and (2) avoiding any edits of Mogenerator's 'machine' classes?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
正如 scc 在之前接受的答案中建议的那样,处理此问题的最终方法是更改 mogenerator 模板文件。他们需要 (a) 将可转换属性的访问器更改为适当的类型(本例中为 NSRange),然后 (b) 使用适当的 KVO 方法调用添加访问器。
由于我现在没有时间弄清楚该怎么做,所以我的临时权宜之计如下:
并不理想,但我确实获得了强类型访问器,而无需编辑 mogenerator 机器文件。
The ultimate way to deal with this would be, as scc suggested in the previously accepted answer, to change the mogenerator template files. They would need to (a) change the transformable attribute's accessor to be of the appropriate type (NSRange in this instance) and then (b) add the accessors with the appropriate KVO method calls.
As that's more than I have time right now to figure out how to do, my temporary expedient is as follows:
Not ideal, but I do get strongly-typed accessors without having to edit the mogenerator machine files.
只需在模型对象生成器完成其工作后将类型从 NSObject 更改为您需要的任何类型即可。此后您不应该收到任何编译器警告。
顺便说一句,当我在定义可转换属性后运行托管对象模型生成器时,我没有得到
NSObject
而是id
。没有警告。Just change the type from
NSObject
to whatever type you need after the model object generator has finished its job. You should not have any compiler warnings after that.BTW, when I run the managed object model generator after defining a transformable attribute I do not get
NSObject
butid
. No warnings.您可以更改 mogenerator 使用的模板文件吗? (我认为)只要您远离标量值,您就可以安全地使用
NSObject *
而不是id
。Can you alter the template files that mogenerator uses? (I think) that provided you stay away from scalar values, you can safely use
NSObject *
instead ofid
.对于那些愿意编辑机器模板文件的人,请使用以下条件来处理可转换 NSRange 属性的特殊情况。
以下是我更改机器模板头文件的方法。 https://gist.github.com/2414047
For those willing to edit the machine template file, use the following conditional to special case for the transformable NSRange attribute.
Here's how I changed my machine template header file. https://gist.github.com/2414047
您正在阅读文档的错误部分。请查看此处:
NSRange
不需要转换。所有这些基本结构都有一些方法,例如:因此,您可以将影子属性定义为类似于
NSString
类型的“rangeAsString
”。在您的 MO 子类中,您将按照文档了解如何正确转换和存储该值,以便核心数据知道您的对象在执行以下操作时变脏:
You are reading the wrong part of the documentation. Please look here:
NSRange
doesn't need to be transformed. There are methods for all those basic structures, such as:So you would define the shadow property as something like "
rangeAsString
" of typeNSString
.In your MO subclass you would follow in the docs on how to properly convert and store the value so that core data knows your object became dirty when doing like: