无法将 String 类型的值转换为预期的参数类型 NSManagedObject

Posted

技术标签:

【中文标题】无法将 String 类型的值转换为预期的参数类型 NSManagedObject【英文标题】:Cannot convert value of type String to expected argument type NSManagedObject 【发布时间】:2017-02-19 04:20:39 【问题描述】:

我正在处理一个 Core Data 项目,但在从 TableViewController 中删除项目时遇到编译器错误:

代码如下:

var listArr:[String] = []

override func viewDidLoad() 
    super.viewDidLoad()
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let context = appDelegate.persistentContainer.viewContext
    let request = NSFetchRequest<NSFetchRequestResult>(entityName:"Entity")
    request.returnsObjectsAsFaults = false

    do 
        let results = try context.fetch(request)

        if results.count > 0 
            for result in results as! [NSManagedObject] 
                if let listName = result.value(forKey: "listName") 
                    listArr.append(listName as! String)
                
            
        
     catch 
        // Handle error
        print(error)
    


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let identifier = "cellID"
    let cell = tableView.dequeueReusableCell(withIdentifier: identifier, for: indexPath)

    // Configure the cell...

    cell.textLabel?.text = listArr[indexPath.row]

    return cell


// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) 
    if editingStyle == .delete 
        // Delete the row from the data source
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let context = appDelegate.persistentContainer.viewContext

        context.delete(listArr[indexPath.row]) //The error is here
        listArr.remove(at: indexPath.row)

    

    self.tableView.reloadData()

我需要改变什么?

【问题讨论】:

【参考方案1】:

您正在调用的delete() 方法将NSManagedObject 作为其唯一参数。您正在从 listArr 数组中传入一个元素,该数组是一个字符串数组。

说起来似乎很明显,但是如果你想删除一个托管对象,你需要告诉Core Data要删除哪个。它不知道如何处理字符串。

猜测(因为你没有说)你的listArr 是由作为实体属性存储在Core Data 中的字符串组成的。您正在某处获取数据并仅保存字符串。 只要您的数据存储是只读的就可以了,至少在应用程序的这一部分中是这样。您可以显示字符串,但不能返回并更新 Core Data,因为您没有必要的信息。

如果是这样,您应该做的是使用托管对象数组而不是字符串数组。当您需要字符串值时,请从其中一个托管对象中获取它。当您需要删除条目时,请删除该托管对象。

【讨论】:

将数组改为[NSManagedObject]后,又出现了一个错误,从NSManagedObject转换为不相关类型'string'总是失败,在cellForRowAt indexPath方法中。【参考方案2】:

您可以通过两种方式从核心数据填充表格。您可以使用NSFetchedResultsController 跟踪核心数据的更改并保持数据同步。或者您可以进行一次提取并将要显示的值存储在我们自己的数据源(例如数组)中。

使用NSFetchedResultsController,您将在数据更改时获得更新。使用此模型,删除行的正确方法是从核心数据中删除它并等待来自NSFetchedResultsController 的回调以更新您的视图。

通过一次提取(正如您所做的那样),您不会在核心数据更改时获得更新。在这个模型中,您可以简单地从数组中删除对象并更新视图。更新核心数据是与您的视图或数据源无关的另一项任务。在这种情况下,您应该使用persistentContainer performBackgroundTask 来获取要删除的对象,然后在后台将其删除。为此,您需要有一种方法来获取要删除的 managedObject。我不知道您存储的是哪种字符串 - 但如果它们是唯一的,您可以将它们用于获取。否则,您还必须存储对象的一些唯一 ID,例如它的 objectID。

【讨论】:

以上是关于无法将 String 类型的值转换为预期的参数类型 NSManagedObject的主要内容,如果未能解决你的问题,请参考以下文章

“无法将 '(String) -> Bool' 类型的值转换为预期参数”

无法将 String 类型的值转换为预期的参数类型 NSManagedObject

无法将“String”类型的值转换为预期的参数类型“URLSession”

如何在此 for 循环中修复'无法将'String'类型的值转换为预期的参数类型'Int'

无法将“NSMutableDictionary”类型的值转换为预期的参数类型“[String: AnyObject]?”

Swift:无法将类型“[String:DayData]”的值转换为预期的参数类型“AnyObject?”