Swift 项目使用 CoreData 可能会碰到的 32 位系统问题
2015-01-08 13:55
337 查看
最近在项目中偶然发现了一个问题,那就是 Swift 的 CoreData 在 32 位系统下与 64 位系统下表现不一致的问题。
简单的说:如果你的 CoreData 模型有一个声明为 Boolean 的 Attribute,并且在代码中使用 NSNumber 来包装(而不是 Bool)的话,很可能会遇到这个问题。
这个问题简述之则是这样:
假如有一个 Post 的 CoreData 类型,它有一个 isPublished 的属性,CoreData 使用 NSNumber 来包装这个属性。我对其进行赋值:
问题就在这里出现了。如果是在 32 位的系统下,我用
如果改成:
发现这个问题的,开始想解决方法,假设这真的是 Swift 在 32 位系统下的 Bug,难道我要把这些比较都改成 1 或 0?
后来我找到一个方法,那就是创建 CoreData 的 NSManagedObject 的 class 的时候,勾上那个 Option:Use scalar properties for primitive data types,这样 isPublished 就不是用 NSNumber 这种包装型的,而是直接用 Bool 类型了。经测试,无论在 32 位系统下还是 64 位系统下,条件判断都工作正常了。算是优雅地绕开了这个可能是 Swift 的 Bug。
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015035/e715f386998f7230cd884ee9000dafb2.png)
后来我又尝试了下不用 CoreData,直接用 NSNumber = false 的形式来进行判断,发现没有这个问题。看来这个问题可能只存在 CoreData 上。
既然写起了 Swift + CoreData 这个组合,免不了需要吐槽一个 Apple 做的还不好的地方:
以往 Objective-C 项目时,CoreData 对象的一个属性是不是空值,我们直接判断是不是 nil 就可以了,但是在 Swift 项目下,一切变得麻烦了,Xcode 默认给我们产生的 CoreData 对象的属性,全都不是optional 的,也就是说,如果一个属性可能是空值,我们还要手动给这个加上一个「?」,它才会如我们所愿可以用 Optional 的方式。这点实在是很不方便。
具体可以看一个帖子:Swift + CoreData: Cannot Automatically Set Optional Attribute On Generated NSManagedObject Subclass
OK,希望接下去不要碰到太多类似的坑。
简单的说:如果你的 CoreData 模型有一个声明为 Boolean 的 Attribute,并且在代码中使用 NSNumber 来包装(而不是 Bool)的话,很可能会遇到这个问题。
这个问题简述之则是这样:
假如有一个 Post 的 CoreData 类型,它有一个 isPublished 的属性,CoreData 使用 NSNumber 来包装这个属性。我对其进行赋值:
post.isPublished = true没错,虽然 isPublished 在代码中是 NSNumber 类型,但是得益于 Swift 的「Literal Convertibles」机制,我们可以直接给 NSNumber 赋值 true,然后它就会以 true 存储。
问题就在这里出现了。如果是在 32 位的系统下,我用
if post.isPublished == true { }进行条件判断,那么很遗憾不会走进这个条件分支里,在 64 位系统下是正常的。
如果改成:
if post.isPublished == 1 { }那么无论在 32 位和 64 位系统下都是正常的。
发现这个问题的,开始想解决方法,假设这真的是 Swift 在 32 位系统下的 Bug,难道我要把这些比较都改成 1 或 0?
后来我找到一个方法,那就是创建 CoreData 的 NSManagedObject 的 class 的时候,勾上那个 Option:Use scalar properties for primitive data types,这样 isPublished 就不是用 NSNumber 这种包装型的,而是直接用 Bool 类型了。经测试,无论在 32 位系统下还是 64 位系统下,条件判断都工作正常了。算是优雅地绕开了这个可能是 Swift 的 Bug。
![](https://oscdn.geek-share.com/Uploads/Images/Content/2015035/e715f386998f7230cd884ee9000dafb2.png)
后来我又尝试了下不用 CoreData,直接用 NSNumber = false 的形式来进行判断,发现没有这个问题。看来这个问题可能只存在 CoreData 上。
既然写起了 Swift + CoreData 这个组合,免不了需要吐槽一个 Apple 做的还不好的地方:
以往 Objective-C 项目时,CoreData 对象的一个属性是不是空值,我们直接判断是不是 nil 就可以了,但是在 Swift 项目下,一切变得麻烦了,Xcode 默认给我们产生的 CoreData 对象的属性,全都不是optional 的,也就是说,如果一个属性可能是空值,我们还要手动给这个加上一个「?」,它才会如我们所愿可以用 Optional 的方式。这点实在是很不方便。
具体可以看一个帖子:Swift + CoreData: Cannot Automatically Set Optional Attribute On Generated NSManagedObject Subclass
OK,希望接下去不要碰到太多类似的坑。
相关文章推荐
- Swift 项目使用 CoreData 可能会碰到的 32 位系统问题
- 精准测试系统推行遇到部分项目32和64位使用问题,没有使用
- 初次使用VS2010基于C++开发项目碰到的问题及解决方法
- win7/8(32/64bit)系统下使用STC-ISP的问题与解决方法(MSCOMM32.OCX)
- 初次使用VS2010基于C++开发项目碰到的问题及解决方法
- 关于SQLlite数据库 在32 位系统上的无法使用的问题
- 初次使用VS2010基于C++开发项目碰到的问题及解决方法
- iOS.swift protocol使用时碰到的小问题
- 最近在使用swift写代码时碰到block引用循环的问题。记下一笔以免忘记。
- 要将程序集“X”标记为系统必备,必须对其进行强签名-使用ClickOnce发布软件时碰到的问题之一
- 初次使用VS2010基于C++开发项目碰到的问题及解决方法
- win7/8(32/64bit)系统下使用STC-ISP的问题与解决方法(MSCOMM32.OCX)
- Spring Boot项目在Mac下使用Maven启动时碰到的神奇问题:Unregistering JMX-exposed beans on shutdown
- 关于RCP中使用系统resource navigator图标和项目名称不显示的问题
- 初次使用VS2010基于C++开发项目碰到的问题及解决方法
- 总结svn使用过程中可能会碰到的问题
- 使用新系统碰到的问题,一起研究一下吧
- 解决 Windows 系统使用 Homestead 运行 Laravel 本地项目响应缓慢问题
- 关于RCP中使用系统resource navigator图标和项目名称不显示的问题
- 初次使用VS2010基于C++开发项目碰到的问题及解决方法