简体   繁体   English

如何在Core Data应用程序中实现只读属性

[英]How to implement a read only attribute in a Core Data app

I'm developing a Core Data app that uses a model object called Location. 我正在开发一个使用名为Location的模型对象的Core Data应用程序。 The user can enter locations and provide their latitude and longitude in decimal format. 用户可以输入位置并以十进制格式提供其经度和纬度。 I use plain NSTextFields for this. 我使用普通的NSTextFields As a feedback to the user, also their degrees/minutes/seconds counterparts are shown (using a label). 作为对用户的反馈,还显示他们的度数/分钟/秒对应物(使用标签)。 The logic for transforming from decimal format to degrees etc. is implemented with the Location model object, which is a subclass of NSManagedObject . 从十进制格式转换为度等的逻辑是使用Location模型对象实现的,该对象是NSManagedObject的子NSManagedObject

Ideally I want to implement these as read-only attributes and have them tied in some way to their decimal counterpart, so that when the user changes the decimal representation, the degrees/minutes/seconds representation gets updated as well. 理想情况下,我希望将它们作为只读属性实现,并将它们以某种方式绑定到它们的十进制对应项,这样当用户更改十进制表示时,度/分/秒表示也会更新。

I've tried the following: 我尝试过以下方法:

  • Set the controller as an NSTextFieldDelegate to intercept edits but this only works if the user actually edits the fields. 将控制器设置为NSTextFieldDelegate以拦截编辑,但这仅在用户实际编辑字段时才有效。 This fails when the user accepts 0 as defaults for both latitude and longitude, which is actually a valid location. 当用户接受0作为纬度和经度的默认值时,这会失败,这实际上是一个有效的位置。
  • I've looked at transient attributes for Core Data but found the documentation on this point not very helpful, although they might be the answer for this... 我已经查看了Core Data的瞬态属性,但发现这方面的文档不是很有帮助,尽管它们可能是这个的答案......

Any ideas on how to approach this? 关于如何处理这个的任何想法?

EDIT: 编辑:

As suggested by Francis McGrew, I implemented the following class method for Location : 正如Francis McGrew所建议的,我为Location实现了以下类方法:

+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key {
    NSSet *result = [super keyPathsForValuesAffectingValueForKey:key];

    if ([key isEqualToString:@"latitudeToDegrees"] || [key isEqualToString:@"longitudeToDegrees"]) {
        result = [result setByAddingObjectsFromSet:[NSSet setWithObjects: @"latitude", @"longitude", nil]];
    }
    return result;
}

Slightly different from his answer, as the DMS is just one attribute represented as a formatted String, calculated by Location . 与他的答案略有不同,因为DMS只是一个属性,表示为格式化的字符串,由Location计算。 I then added bindings in the UI to latitudeToDegrees and longitudeToDegrees and ...boom!.., a nicely updated UI. 然后我在UI中添加了绑定到latitudeToDegreeslongitudeToDegrees以及...... boom!..,一个很好的更新的UI。

If someone could explain transient properties to me I'd love to hear it as well. 如果有人可以向我解释瞬态属性,我也很乐意听到它。

Since DMS is easily calculated from the latitude and longitude, there's no real reason to store those values as attributes in your model. 由于可以从纬度和经度轻松计算DMS,因此没有理由将这些值存储为模型中的属性。 I would just write methods that calculate and return the current degrees, minutes and seconds based on the saved latitude and longitude attributes. 我只会根据保存的纬度和经度属性编写计算并返回当前度,分和秒的方法。

Then, to have Core Data automatically notify obervers of changes, you would implement the following method in your Location class: 然后,要让Core Data自动通知obervers更改,您可以在Location类中实现以下方法:

+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key {
    NSSet *result = [super keyPathsForValuesAffectingValueForKey:key];

    if ([key isEqualToString:@"degrees"] ||
        [key isEqualToString:@"minutes"] ||
        [key isEqualToString:@"seconds"]) {

        result = [result setByAddingObjectsFromSet:[NSSet setWithObjects:
            @"latitude", @"longitude", nil]];
    }
    return result;

} }

This tells Core Data that the "transient" degrees, minutes and seconds are dependent on your latitude and longitude attributes. 这告诉Core Data“瞬态”度,分和秒取决于您的纬度和经度属性。 Assuming you're using bindings, your user interface should update automatically. 假设您正在使用绑定,您的用户界面应自动更新。 To prevent the user from editing the text fields, just set their behavior to "Selectable" or "None" in your XIB. 要防止用户编辑文本字段,只需在XIB中将其行为设置为“可选”或“无”。 (In XCode 3 I think you just uncheck the "Editable" box) (在XCode 3中,我认为你只需取消选中“可编辑”框)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM