我已經嘗試了所有我能找到的當前 StackOverflow 建議,但似乎沒有一個有效,所以我必須求助于自己。
我正在嘗試從填充了自定義單元格的 tableView 中洗掉日記條目。(所有日志條目都是在用戶輸入上創建的,然后存盤在 CoreData 中,UITableView 填充有來自 CoreData 的這些條目)。
洗掉表格視圖單元格時,條目已成功洗掉,但應用程式因錯誤而崩潰
Terminating app due to uncaught exception 'NSInternalInconsistencyException'
如果我重新加載應用程式并使用此 tableView 轉到頁面,則 TableView 中不再存在該條目,因此它正在從 CoreData 中洗掉,而不是從表中洗掉。對此的任何幫助將不勝感激!
拋出錯誤的函式如下:
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
print("table view index cell \(tableView.indexPathsForVisibleRows!)")
if editingStyle == .delete {
print("Deleting Journal Entry from Core Data")
let managedContext = appDelegate.persistentContainer.viewContext
managedContext.delete(fetchedResultsController.object(at: indexPath))
do {
try managedContext.save()
} catch {
print("error saving after deleting")
}
// THIS LINE THROWS THE ERROR :(
tableView.deleteRows(at: [indexPath], with: .fade)
}
}
整個 ViewController 類代碼:
import UIKit
import CoreData
import Foundation
class JournalListViewController: UIViewController, UITableViewDelegate,
UITableViewDataSource, NSFetchedResultsControllerDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate{
@IBOutlet weak var journalTableView: UITableView!
@IBOutlet weak var noEntriesLabel: UILabel!
let parks = NationalPark.getAllParks()
let dateFormatter = DateFormatter()
var journalIndex = Int()
var journalImage = UIImage()
let appDelegate = UIApplication.shared.delegate as! AppDelegate
// Core data set up
lazy var fetchedResultsController: NSFetchedResultsController<Entry> = {
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest: NSFetchRequest<Entry> = Entry.fetchRequest()
fetchRequest.sortDescriptors = [NSSortDescriptor (key: "park", ascending: true)]
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedContext, sectionNameKeyPath: nil, cacheName: nil)
fetchedResultsController.delegate = self
return fetchedResultsController
} ()
override func viewDidLoad() {
super.viewDidLoad()
self.journalTableView.delegate = self
self.journalTableView.dataSource = self
// Needed to Fetch Core Data
do {
try fetchedResultsController.performFetch()
print ("fetched")
} catch {
let fetchError = error as NSError
print("\(fetchError) , \(fetchError.localizedDescription)")
}
}
// MARK: - Navigation
// Prepare segue to New Entry Controller
// Pass the index of list items, connected to image saving
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toNewEntry" {
let destinationVC = segue.destination as! NewJournalEntryViewController
destinationVC.index = journalIndex;
}
else if segue.identifier == "toJournalEntryData" {
let destinationVC = segue.destination as! JournalDataViewController
let selectedJournalEntry: Entry = fetchedResultsController.object(at: journalTableView.indexPathForSelectedRow!)
// GET IMAGE FOR SELECTED JOURNAL CELL FROM SAVED DOCUMENTS
// then set image to UIImage for Data View
let imageURL = getDocumentsDirectory().appendingPathComponent("image\(selectedJournalEntry.entryNum).jpg")
let image = UIImage(contentsOfFile: imageURL.path)
// print("\(journalImage)")
destinationVC.journalImage = image!
// print("THE RETURN PATH IS ****** \(imageURL)")
// STORE INFORMATION INTO DESTINATION VIEW VARIABLES
destinationVC.title = "Journal Entry"
// destinationVC.journalEntryNum = selectedJournalEntry.entryNum
destinationVC.journalTitle = selectedJournalEntry.park!
destinationVC.journalDate = String(journalIndex)
destinationVC.journalReport = selectedJournalEntry.report!
}
}
func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return paths[0]
}
// MARK: - Table View Methods
// Defines # Of Rows In TableView
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let journalEntries = fetchedResultsController.fetchedObjects
else {
return 0
}
print("Journal Entries \(journalEntries.count)")
if (journalEntries.count == 0) {
noEntriesLabel.text = "You have no journal entries :("
noEntriesLabel.isHidden = false
} else { noEntriesLabel.isHidden = true
journalIndex = journalEntries.count
}
return journalEntries.count
}
// Configure each table row cell
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Core Data Cell Getter
guard let cell = tableView.dequeueReusableCell(withIdentifier: "JournalTableCell", for: indexPath) as? JournalListTableViewCell else {
fatalError("expected Index path")
}
// Get the journalEntry number from core data to correspond with each cell
let journalEntry = fetchedResultsController.object(at: indexPath)
// SAME CODE FROM ABOVE IN THE SEGUE!
// Gets Image from documents and sets it to the Image of the cell
let imageURL = getDocumentsDirectory().appendingPathComponent("image\(journalEntry.entryNum).jpg")
let image = UIImage(contentsOfFile: imageURL.path)
// print("IMAGE AT CELL \(journalEntry): \(imageURL.path)")
cell.journalImageView.image = image!
// END SAME CODE
// var dateInStringFormat = (dateFormatter.string(from: journalEntry.date!))
cell.journalTitleLabel.text = journalEntry.park
cell.journalDateLabel.text = String(journalEntry.entryNum)
// cell.journalDateLabel.text = dateInStringFormat
// configure cell styling
cell.configure()
return cell
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
return .delete
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
print("table view index cell \(tableView.indexPathsForVisibleRows!)")
if editingStyle == .delete {
print("Deleting Journal Entry from Core Data")
let managedContext = appDelegate.persistentContainer.viewContext
managedContext.delete(fetchedResultsController.object(at: indexPath))
do {
try managedContext.save()
} catch {
print("error saving after deleting")
}
tableView.deleteRows(at: [indexPath], with: .fade)
}
}
// Anytime the View Appears, refresh for new data
override func viewDidAppear(_ animated: Bool) {
// Needed to Fetch Core Data
do {
try fetchedResultsController.performFetch()
print ("fetched")
} catch {
let fetchError = error as NSError
print("\(fetchError) , \(fetchError.localizedDescription)")
}
getAllItems()
}
// Simply reloads table view
func getAllItems() {
journalTableView.reloadData()
}
}
uj5u.com熱心網友回復:
使用NSFetchedResultsController(FRC) 時,您不需要也不應該自己洗掉表行。
只需實作 FRC 委托方法controller(_:didChange:at:for:newIndexPath:)。
然后在此方法中執行以下操作(取決于您的部分):
let range = NSMakeRange(0, tableView.numberOfSections)
let sections = NSIndexSet(indexesIn: range)
tableView.reloadSections(sections as IndexSet, with: .automatic)
所以洗掉tableView.deleteRows(at: [indexPath], with: .fade)并執行上述內容。
這應該可以解決您在那條線上的崩潰問題,但我沒有檢查其他事情是否有問題。
祝你好運!
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/472725.html
上一篇:如何根據大小檢查dylib內容?
