2016-10-29 44 views
1

我正在使用sqlite作爲底層存儲的CoreData堆棧上工作。我的模式看起來是這樣的:最快的方式檢索NSManagedObjects基於屬性的對多關係

Data Model

的圖像可以有多個標籤,一個標籤可以屬於多個圖像。我的用例是能夠搜索匹配特定標籤名稱的圖像。標籤的name屬性被編入索引。

我在我的ViewController中使用FetchedResultsController來填充所需圖像的CollectionView。最初,我將謂詞作爲零傳遞,但在搜索時,我需要顯示相關結果,即與具有指定標記名稱的標記匹配的圖像。以下是我的FetchedResultsController初始化方法。

func initialiseFetchedResultsControllerWith(_ predicate: NSPredicate) { 

     //If the FRC is already initialised then just change the predicate and fetch again 

     if fetchedResultsController != nil { 
      fetchedResultsController.fetchRequest.predicate = predicate 
     } else { 
      let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "SMImage") 
      let timestampSortDescriptor = NSSortDescriptor(key: "timestamp", ascending: false) 
      fetchRequest.sortDescriptors = [timestampSortDescriptor] 
      fetchRequest.predicate = predicate 

      fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DataStoreController.sharedController.managedObjectContext!, sectionNameKeyPath: nil, cacheName: nil) 
      fetchedResultsController.delegate = self 
     } 

     do { 
      try self.fetchedResultsController.performFetch() 
     } catch { 
      print("Error in fetching image obbject via FRC => \(error)") 
     } 

    } 

我需要傳遞一個謂詞到FetchedResultsController來獲取圖像。我想到兩種方法:

  1. 獲取objectIDs包含搜索字符串的所有SMTags,然後查詢包含這些objectID的SMImages。

     let fetchRequest = NSFetchRequest<NSManagedObjectID>(entityName: "SMTag") 
        fetchRequest.predicate = NSPredicate(format: "name contains[cd] %@", text) 
        fetchRequest.resultType = NSFetchRequestResultType.managedObjectIDResultType 
        var tagIDs: Array<NSManagedObjectID>? = nil 
    
        do { 
        tagIDs = try DataStoreController.sharedController.managedObjectContext!.fetch(fetchRequest) 
        } catch { 
        print("Error in retreiving tags with names = \(error)") 
        } 
    
    
    
        if tagIDs != nil { 
        predicate = NSPredicate(format: "tags IN %@", NSSet(array: tagIDs!)) 
        } 
    

這種方法不會返回tagIDs但不返回任何圖像。

  • 的另一種方法是使用謂詞直接搜索上的圖像SMTag的名字:

    predicate = NSPredicate(format: "ANY tags.name contains[cd] %@", text) 
    
  • 如果您知道任何更好的辦法請不要建議。任何幫助表示讚賞。

    回答

    0

    這兩種方法都不能很好地利用核心數據。你有多對多的關係,爲什麼不使用它?更好的方法是:

    1. 獲取包含搜索詞的單個SMTag。這與代碼片段的第一部分非常相似,除了您可以獲取託管對象而不是對象ID。

    2. 通過在SMTag上使用images關係獲取與標籤關聯的所有圖像。如果你有一個SMTag的自定義類,這將是類似於fetchedTag.images。如果不是的話,它會像fetchedTag.value(forKey:"images")

    +0

    感謝您回覆@tom。這種方法的問題是我使用fetchResultsController,因此我需要將一個謂詞傳遞給fetchedResultsController以便能夠檢索圖像。你提出的方法在這種情況下將不起作用。我在這個問題中增加了更多信息。 – jarora

    +0

    您無需使用'NSFetchedResultsController' –

    +0

    如果您嘗試管理大量對象,內存管理就成了一個問題。另外FetchedResultsController通常提供很多便利。你能指導我一個解決方案,與FetchedResultsController一起工作嗎? – jarora

    相關問題