[英]Issue with fetching Core Data managed object using NSPredicate by object's enum attribute
我在獲取具有Int16
rawValues 的enum
屬性的 Core Data 托管對象時遇到問題。 調用NSPredicate(format:)
時程序崩潰。
這是導致崩潰的代碼(第 3 行):
func returnBook (bookType: BookType) -> Book? {
let fetchRequest = NSFetchRequest<Book>(entityName: "Book")
fetchRequest.predicate = NSPredicate(format: "%K = %@", #keyPath(Book.bookType), bookType.rawValue as CVarArg)
fetchRequest.fetchLimit = 1
let book = (try? fetchRequest.execute())?.first
return book
}
崩潰消息是:
線程 1:EXC_BAD_ACCESS(代碼=1,地址=0x3)
當我使用以下內容更改第 3 行時,出現另一種錯誤。
這是替代代碼:
fetchRequest.predicate = NSPredicate(format: "%K = %@", #keyPath(Book.bookType), bookType as! CVarArg)
這是該替代代碼導致的錯誤:
線程 1:信號 SIGABRT
我在調試輸出中看到了這一點:
無法將“ProjectName.BookType”(0x10ac10098)類型的值轉換為“Swift.CVarArg”(0x10b698548)。
以下是項目中的其他一些相關代碼:
@objc(Book)
public class Book: NSManagedObject {
// …
}
extension Book {
@NSManaged public var bookType: BookType
}
@objc public enum BookType: Int16 {
case fiction = 0
case nonFiction = 1
case reference = 2
}
我的問題:如何使用bookType
屬性從我的 Core Data 存儲中正確獲取Book
對象,該屬性位於具有Int16
rawValues 的@objc enum
類型中?
更新:
我已經按照 Jesse Squires 的演示文稿中的建議嘗試了其他方法:
enum
的定義中刪除了@objc
關鍵字private
和public
屬性來訪問enum
的實例... 我已按照鏈接演示文稿中的建議更改了代碼,並將 Core Data 的“.xcdatamodeld”文件中的bookType
屬性名稱更改為bookTypeValue
。
extension Book {
public var bookType: BookType {
get {
return BookType(rawValue: self.bookTypeValue)!
}
set {
self.bookTypeValue = newValue.rawValue
}
}
@NSManaged private var bookTypeValue: Int16
}
public enum BookType: Int16 {
case fiction = 0
case nonFiction = 1
case reference = 2
}
我嘗試使用上面鏈接的演示文稿中建議的私有值來獲取...:
fetchRequest.predicate = NSPredicate(format: "bookTypeValue == %@", bookType)
但是我也無法用這種方法解決我的問題...... XCode 立即抱怨:
參數類型“BookType”不符合預期類型“CVarArg”
如果我改用bookType.rawValue
XCode 就會停止抱怨。 但是,程序在運行時崩潰並出現上述相同的錯誤(第一個)。
更新 2:
我已經應用了社區建議的這個問題的答案。 更具體地說,我在使用%i
或@ld
而不是%@
問題的答案中嘗試了建議,如下所示:
fetchRequest.predicate = NSPredicate(format: "bookTypeValue == %i", bookType.rawValue)
我已經嘗試了另一個使用字符串插值的建議,如下所示:
fetchRequest.predicate = NSPredicate(format: "bookTypeValue == %@", "\(bookType.rawValue)")
這些代碼更改防止了崩潰,但 func returnBook
返回 nil,即使我確定數據在那里。 由於某種原因,獲取或比較失敗...
在為這個問題苦苦掙扎了幾個小時后,我終於設法解決了它。
以下是我為按時間順序解決問題所做的工作:
bookTypeValue
的類型從Int16
更改為Int32
,因為我在官方(存檔) 文檔中看不到 16 位整數的格式說明符。 我已經測試過,我可以確認,如果您在此處使用%@
而不是正確的格式說明符(對於有符號 32 位整數是%d
,您會得到問題中的第一個錯誤:線程 1:EXC_BAD_ACCESS(代碼=1,地址=0x3)
我已經更改了NSPredicate(format:)
調用,如下所示:
fetchRequest.predicate = NSPredicate(格式:"bookTypeValue == %d", bookType.rawValue)
我已經更改了returnBook
func 中的第 5 行, returnBook
所示:
do { let results = try coreDataStack.managedContext.fetch(fetchRequest) if results.count > 0 { book = results.first return book } } catch let error as NSError { print("Fetch error: \\(error) description: \\(error.userInfo)") }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.