xcode 如何在 Swift 中表示 Core Data 可选标量(Bool/Int/Double/Float)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42622638/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 09:49:45  来源:igfitidea点击:

How to represent Core Data optional Scalars (Bool/Int/Double/Float) in Swift?

iosswiftxcodecore-data

提问by Nikolay Suvandzhiev

(first noticed on: Xcode 8.2.1, iOS 10, Swift 3) (still present as of: Xcode 9 beta 3, iOS11, Swift 4)

(首次注意到:Xcode 8.2.1、iOS 10、Swift 3)(仍然存在于:Xcode 9 beta 3、iOS11、Swift 4)

We all know that the Core Dataconcept of optionalsprecedes and is not strictly tied to the Swiftconcept of optionals.

我们都知道,Core Data概念optionals先于 ,并且与 的Swift概念没有严格的联系optionals

And we have accepted that even if a Core Dataattribute is marked as Non-optional, the auto-generated NSManagedObjectsubclass has an optionaltype:

我们已经接受即使一个Core Data属性被标记为Non-optional,自动生成的NSManagedObject子类也有一个optional类型:

(some people manually remove the ?with no adverse effects, some don't, but that's beside the point)

(有些人手动删除?没有任何不利影响,有些人没有,但这无关紧要)

(From here on the example and screenshots are for Boolproperties, but same goes for Int16/32/64, Double, Float)

(从这里开始,示例和屏幕截图用于Bool属性,但同样适用于Int16/32/64, Double, Float

Now I noticed the reverse - when a Core Dataattribute of type Boolis marked as Optional(and Use Scalar Typeis chosen, which Xcode does by default), the auto-generated class has a variable of a non-optionaltype.

现在我注意到了相反的情况——当一个Core Data类型的属性Bool被标记为Optional(并被Use Scalar Type选中,Xcode 默认这样做)时,自动生成的类有一个non-optional类型的变量。

Does this make sense? Is it a bug? Is the behaviour documented anywhere?

这有意义吗?这是一个错误吗?该行为是否记录在任何地方?

And most importantly - how do I actually represent an optional Bool?

最重要的是 - 我如何实际表示一个 optional Bool

I can think of some work-arounds, but they don't seem ideal (e.g. not using scalars, but going back to NSNumberrepresentation of the Bool. Or (even worse) having a separate Boolcalled something like isVerified_isSet)

我可以想到一些变通办法,但它们似乎并不理想(例如,不使用标量,而是回到 的NSNumber表示Bool。或者(甚至更糟)有一个单独的Bool名称,例如isVerified_isSet



Note: I did a couple more tests and if the Default Valueis set to Noneor to NO, then the variable gets saved as false(even if I never actually assign it in my code). If the Default Valueis set to YES, then the variable gets saved as true. Still, this means that (apparently) there is no way to logically represent this variable as not having been set yet.

注意:我进行了更多测试,如果Default Value设置为NoneNO,则变量将保存为false(即使我从未在代码中实际分配过它)。如果Default Value设置为YES,则变量将保存为true。尽管如此,这意味着(显然)没有办法在逻辑上将此变量表示为尚未设置。

采纳答案by Tom Harrington

I see the same thing, and I consider it to be a bug. It's not documented anywhere that I can find. Apparently Core Data is applying Objective-C style assumptions here, where a boolean defaults to NO, and an integer defaults to 0. The Core Data/Swift interface has some rough edges, and this is one I hadn't considered before.

我看到了同样的事情,我认为这是一个错误。在我能找到的任何地方都没有记录。显然,Core Data 在这里应用了 Objective-C 风格的假设,其中布尔值默认为NO,整数默认为 0。Core Data/Swift 接口有一些粗糙的边缘,这是我以前没有考虑过的。

It's a good find but I think you're stuck with it until Apple addresses it. You already know the best workarounds, which I agree aren't great. I recommend filing a bug.

这是一个很好的发现,但我认为在 Apple 解决它之前你会坚持下去。您已经知道最好的解决方法,我同意这些方法并不好。我建议提交一个错误。

回答by Arek

This happens because Objective-C scalar types do not have a notion of nil value. Source: handling-core-data-optional-scalar-attributes

发生这种情况是因为 Objective-C 标量类型没有 nil 值的概念。来源:处理核心数据可选标量属性

回答by future-adam

If you end up here with this:

如果你最终在这里:

@NSManaged var boolAttribute: Bool

and it is not being seen in Objective-C, andyou have already disabled "Optional" and enabled "Use Scalar Type" on those attributes, then do yourself a favour.

并且它在 Objective-C 中看不到,并且您已经在这些属性上禁用了“可选”并启用了“使用标量类型”,然后帮自己一个忙。

Double check you have imported your Swift bridging header into that Objective-C file.

仔细检查您是否已将 Swift 桥接头导入到该 Objective-C 文件中。

I did not and, well, I was most of the way to changing my Bools to NSNumbers before smacking my head and realising how foolish I had been.

我没有,好吧,在拍我的头并意识到我是多么的愚蠢之前,我大部分时间都将我的 Bools 更改为 NSNumbers。