无法将 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]?”