歡迎加入QQ討論群258996829
Swift 頭像
蘋果5袋
5
Swift

Swift 項目使用 CoreData 可能會碰到的 32 位系統(tǒng)問題

發(fā)布時間:2014-12-27 20:25  回復(fù):0  查看:2774   最后回復(fù):2014-12-27 20:25  


最近在項目中偶然發(fā)現(xiàn)了一個問題,那就是 Swift 的 CoreData 在 32 位系統(tǒng)下與 64 位系統(tǒng)下表現(xiàn)不一致的問題。

簡單的說:如果你的 CoreData 模型有一個聲明為 Boolean 的 Attribute,并且在代碼中使用 NSNumber 來包裝(而不是 Bool)的話,很可能會遇到這個問題。

這個問題簡述之則是這樣:

假如有一個 Post 的 CoreData 類型,它有一個 isPublished 的屬性,CoreData 使用 NSNumber 來包裝這個屬性。我對其進行賦值:

post.isPublished = true

沒錯,雖然 isPublished 在代碼中是 NSNumber 類型,但是得益于 Swift 的「Literal Convertibles」機制,我們可以直接給 NSNumber 賦值 true,然后它就會以 true 存儲。

問題就在這里出現(xiàn)了。如果是在 32 位的系統(tǒng)下,我用

if post.isPublished == true {
}

進行條件判斷,那么很遺憾不會走進這個條件分支里,在 64 位系統(tǒng)下是正常的。

如果改成:

if post.isPublished == 1 {
}


那么無論在 32 位和 64 位系統(tǒng)下都是正常的。

發(fā)現(xiàn)這個問題的,開始想解決方法,假設(shè)這真的是 Swift 在 32 位系統(tǒng)下的 Bug,難道我要把這些比較都改成 1 或 0?

后來我找到一個方法,那就是創(chuàng)建 CoreData 的 NSManagedObject 的 class 的時候,勾上那個 Option:Use scalar properties for primitive data types,這樣 isPublished 就不是用 NSNumber 這種包裝型的,而是直接用 Bool 類型了。經(jīng)測試,無論在 32 位系統(tǒng)下還是 64 位系統(tǒng)下,條件判斷都工作正常了。算是優(yōu)雅地繞開了這個可能是 Swift 的 Bug。

core-data-scalar-properties.png

后來我又嘗試了下不用 CoreData,直接用 NSNumber = false 的形式來進行判斷,發(fā)現(xiàn)沒有這個問題。看來這個問題可能只存在 CoreData 上。

既然寫起了 Swift + CoreData 這個組合,免不了需要吐槽一個 Apple 做的還不好的地方:

以往 Objective-C 項目時,CoreData 對象的一個屬性是不是空值,我們直接判斷是不是 nil 就可以了,但是在 Swift 項目下,一切變得麻煩了,Xcode 默認給我們產(chǎn)生的 CoreData 對象的屬性,全都不是optional 的,也就是說,如果一個屬性可能是空值,我們還要手動給這個加上一個「?」,它才會如我們所愿可以用 Optional 的方式。這點實在是很不方便。

具體可以看一個帖子:Swift + CoreData: Cannot Automatically Set Optional Attribute On Generated NSManagedObject Subclass

(本文作者:圖拉鼎)

您還未登錄,請先登錄

熱門帖子

最新帖子

?