1

Я работаю над проектом Core Data, и я получил ошибку компилятора для удаления элемента из TableViewController:Невозможно преобразовать значение типа String, ожидаемого тип аргумента NSManagedObject

Невозможно преобразовать значение типа String, ожидаемый типа аргумента NSManagedObject

Вот код:

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, потому что у вас нет необходимой информации.

Если это правда, вам следует использовать массив управляемых объектов вместо массива строк. Когда вам нужно значение строки, получите его из одного из управляемых объектов. Когда вам нужно удалить запись, удалите этот управляемый объект.

+0

После изменения массива на [NSManagedObject] произошла другая ошибка, которая была перенесена из NSManagedObject в несвязанный тип «string», всегда в методе cellForRowAt indexPath. –

0

Существует два способа заполнения таблицы из данных ядра. Либо вы можете использовать NSFetchedResultsController, который отслеживает изменения из основных данных и синхронизирует ваши данные. Или вы можете сделать одну выборку и сохранить значения, которые вы хотите отобразить, в нашем собственном источнике данных (например, в массиве).

С NSFetchedResultsController вы будете получать обновления по мере изменения ваших данных. С помощью этой модели правильным способом удаления строки является удаление ее из основных данных и ожидание обратного вызова из NSFetchedResultsController для обновления вашего представления.

С одной выборкой (как вы это делаете) вы не получаете обновлений в виде изменений в базе данных. В этой модели вы можете просто удалить объект из своего массива и обновить представление. Обновление основных данных - это еще одна задача, не связанная с вашим представлением или источником данных. В этом случае вы должны использовать persistentContainerperformBackgroundTask, чтобы получить объект, который хотите удалить, а затем удалить его в фоновом режиме. Для этого вам нужно иметь способ получить управляемый объект, который вы хотите удалить. Я не знаю, какие строки вы храните, но если они уникальны, вы можете использовать их для своей выборки. В противном случае вам также потребуется сохранить уникальный идентификатор объекта, например, его идентификатор объекта.

 Смежные вопросы

  • Нет связанных вопросов^_^