Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2623227
  • 博文数量: 877
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 5921
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-05 12:25
个人简介

技术的乐趣在于分享,欢迎多多交流,多多沟通。

文章分类

全部博文(877)

文章存档

2021年(2)

2016年(20)

2015年(471)

2014年(358)

2013年(26)

分类: iOS平台

2015-10-18 22:42:57

use scalar properties for primitive data types

If you have "Use scalar properties for primitive data types" selected when you generated the NSManagedObject subclasses for your entities, it will use scalar properties like int and float instead of NSNumbers, which take up more memory. This includes NSDate; It will turn NSDate into an NSTimeInterval which is just a double. This NSTimeInterval is a time interval since the 1970 standard epoch used by Apple (if it's before 1970 it probably is negative).
It's pretty simple to convert the NSTimeInterval back into an NSDate if you need it to, but if you don't have a huge database, then you might not want to bother selecting that checkbox.

To convert this time interval into an NSDate just use [NSDate dateWithTimeIntervalSince1970: timeInterval]; where timeInterval is what you get from the database. This can be put in your NSManagedObject subclass so that when you get that property, you get an NSDate anyway.

最近在项目中偶然发现了一个问题,那就是 Swift 的 CoreData 在 32 位系统下与 64 位系统下表现不一致的问题。

简单的说:如果你的 CoreData 模型有一个声明为 Boolean 的 Attribute,并且在代码中使用 NSNumber 来包装(而不是 Bool)的话,很可能会遇到这个问题。

这个问题简述之则是这样:

假如有一个 Post 的 CoreData 类型,它有一个 isPublished 的属性,CoreData 使用 NSNumber 来包装这个属性。我对其进行赋值:

1
post.isPublished = true

没错,虽然 isPublished 在代码中是 NSNumber 类型,但是得益于 Swift 的「Literal Convertibles」机制,我们可以直接给 NSNumber 赋值 true,然后它就会以 true 存储。

问题就在这里出现了。如果是在 32 位的系统下,我用

1
2
if post.isPublished == true {
}

进行条件判断,那么很遗憾不会走进这个条件分支里,在 64 位系统下是正常的。

如果改成:

1
2
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。

core-data-scalar-properties.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

阅读(830) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~