0

1つのビューコントローラに2つのテーブルビューがあり、どちらも互いに関連しない別々のタイプのデータを保持しています。何らかの理由で、いずれかのプロジェクトに新しいデータを追加するたびに、アプリケーションがクラッシュします。新しいデータが両方のテーブルビューに1つではなく新しいテーブルに追加されるためです。私は、正しいテーブルビューにデータを追加しようとしています。ここに私のコードです。テーブルビューにコアデータを追加するとアプリケーションがクラッシュする

var tasks: Todo! 
var progress: [Millestone] = [] 
var milestone: Millestone! 
var list: [Todo] = [] 

var taskfetch: NSFetchedResultsController<Todo>! 
var progressfetch : NSFetchedResultsController<Millestone>! 


    let fetching: NSFetchRequest<Todo> = Todo.fetchRequest() 
    let sorting = NSSortDescriptor(key: "dateadded", ascending: true) 
    fetching.predicate = NSPredicate(format: "projectname = %@", "\(title! as String)") 
    fetching.sortDescriptors = [sorting] 
    if let appDelegate = (UIApplication.shared.delegate as? AppDelegate) { 
     let context = appDelegate.persistentContainer.viewContext 
     taskfetch = NSFetchedResultsController(fetchRequest: fetching, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil) 
     taskfetch.delegate = self 

     do { 
      try taskfetch.performFetch() 
      if let fetchedObjects = taskfetch.fetchedObjects { 
       list = fetchedObjects 
      } 
     } catch { 
      print(error) 
     } 
    } 

    let lining: NSFetchRequest<Millestone> = Millestone.fetchRequest() 
    let sorting2 = NSSortDescriptor(key: "dateadded", ascending: true) 
    lining.predicate = NSPredicate(format: "projectname = %@", "\(title! as String)") 
    lining.sortDescriptors = [sorting2] 
    if let appDelegate = (UIApplication.shared.delegate as? AppDelegate) { 
     let context = appDelegate.persistentContainer.viewContext 
     progressfetch = NSFetchedResultsController(fetchRequest: lining, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil) 
     progressfetch.delegate = self 

     do { 
      try progressfetch.performFetch() 
      if let fetchedObjects = progressfetch.fetchedObjects { 
       progress = fetchedObjects 
      } 
     } catch { 
      print(error) 
     } 
    } 
func getdata() { 
    let context = (UIApplication.shared.delegate as! AppDelegate!).persistentContainer.viewContext 

    do { 
     print("getting") 


     let tasking = try context.fetch(Todo.fetchRequest()) 


     let progressname = try context.fetch(Millestone.fetchRequest()) 
    } catch{ 
     print("whoopsie") 
    } 
} 
let oktaskaction = UIAlertAction(title: "Add", style: .default, handler: {(action:UIAlertAction!) -> Void in 

     if text.textFields?[0].text != nil, text.textFields?[0].text != "" { 
      // self.taskTable.beginUpdates() 
      // let song = self.songs[indexPath.row] 
      //(UIApplication.shared.delegate as! AppDelegate).saveContext() 
      if let appDelegate = (UIApplication.shared.delegate as? AppDelegate){ 
       self.tasks = Todo(context: appDelegate.persistentContainer.viewContext) 
       self.tasks.taskname = text.textFields?[0].text 
       self.tasks.projectname = self.title 
       self.tasks.completed = false 
       let formatter = DateFormatter() 
       formatter.dateStyle = DateFormatter.Style.medium 
       formatter.timeStyle = DateFormatter.Style.none 
       self.tasks.dateadded = self.date 
       appDelegate.saveContext() 
      }else { 
       print("nothing there") 
       text.textFields?[0].placeholder = "did not enter text" 
      } 
      self.taskTable.refreshControl?.beginRefreshing() 
      self.getdata() 
      self.taskTable.reloadData() 

     } 

    }) 


    let okAction = UIAlertAction(title: "Add Milestone", style: .default, handler: {(action:UIAlertAction!) -> Void in 
     if text2.textFields?[0].text != nil, text2.textFields?[0].text != "", text2.textFields?[1].text != nil { 
      print("i'm working on adding the milestone") 
      if let appDelegate = (UIApplication.shared.delegate as? AppDelegate){ 
       self.milestone = Millestone(context: appDelegate.persistentContainer.viewContext) 
       self.milestone.progressname = text2.textFields?[0].text 
       self.milestone.date = text2.textFields?[1].text 
       self.milestone.projectname = self.title 
       appDelegate.saveContext() 
        print("adding to graph") 
        self.chartLegend.append(self.milestone.progressname!) 
        self.chartData.append(self.chartData.count + 1) 


       print("saved the new milestone") 
      }else { 
       print("nothing there") 
       text.textFields?[0].placeholder = "did not enter text" 
      } 
      self.milestoneTableView.reloadData() 
      self.projectlinechart.reloadData() 

     } 

    }) 
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { 
    print("Begining") 
    print("\(list.count)") 
    print("\(progress.count)") 
    taskTable.beginUpdates() 
    milestoneTableView.beginUpdates() 

} 
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) { 
    switch type { 
    case .insert: 

     if let newIndexPath = newIndexPath { 
       print("adding") 

      taskTable.insertRows(at: [newIndexPath], with: .fade) 
      milestoneTableView.insertRows(at: [newIndexPath], with: .fade) 

     } 
    case .delete: 
     if let indexPath = indexPath { 
      print("delete") 
      taskTable.deleteRows(at: [indexPath], with: .fade) 
      milestoneTableView.deleteRows(at: [indexPath], with: .fade) 

     } 
    case .update: 
     if let indexPath = indexPath { 
      print("updating") 
      taskTable.reloadRows(at: [indexPath], with: .fade) 
      milestoneTableView.reloadRows(at: [indexPath], with: .fade) 

     } 
    default: 
     print("doing something else") 
     taskTable.reloadData() 
     milestoneTableView.reloadData() 

    } 

    if let fetchedObjects = controller.fetchedObjects { 
     projects = fetchedObjects as! [Project] 
     list = fetchedObjects as! [Todo] 
     progress = fetchedObjects as! [Millestone] 
    } 
} 
    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { 
     print("ending") 
     print("\(list.count)") 
     print("\(progress.count)") 
     taskTable.endUpdates() 
     milestoneTableView.endUpdates() 



    } 
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    if tableView.tag == 1 { 
     return list.count 
    } else if tableView.tag == 2 { 
     return progress.count 
    } else { 
     return 0 
    } 
     } 


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cellidentifier = "taskcell" 

    let cell = tableView.dequeueReusableCell(withIdentifier: cellidentifier, for: indexPath) as! TaskTableViewCell 
    if tableView.tag == 1 { 
     let tasks = list[indexPath.row]//this is where the crash occurs 
     cell.taskname.text = tasks.taskname 
     cell.taskname.adjustsFontSizeToFitWidth = true 
     if tasks.completed == true { 
      cell.accessoryType = .checkmark 
     } 



    } 
    } else if tableView.tag == 2 { 
     if let appDelegate = (UIApplication.shared.delegate as? AppDelegate){ 
      let progress2 = progress[indexPath.row] 
      if (progress2.progressname != nil), progress2.date != nil{ 
      cell.progressname.text = "\(progress2.progressname!) on \(progress2.date!)" 
      cell.progressname.adjustsFontSizeToFitWidth = true 
      self.chartData.append(self.chartData.count + 1) 
      chartLegend.insert(cell.progressname.text!, at: indexPath.row) 
      } else { 
       cell.progressname.text = "No Milestones" 
      } 

     } 

    } 


    return cell 
} 
+0

アプリがクラッシュする場所と受け取ったエラーメッセージを共有できますか? –

+0

このコードでアプリケーションがクラッシュすることを確認してください。task = list [indexPath.row] NSArray要素がSwift Arrayと一致しませんでした。 –

+0

例外ブレークポイントを追加してもう一度実行してください。一般に、それがコアデータの問題であれば、何がうまくいっているのかを明確に報告し、その行で停止します。コンソール出力を共有することも非常に便利です。 –

答えて

0

progresslistの変数を削除してください。 fetchedResultsControllerはオブジェクトの変更を追跡しているので、オブジェクトが削除または挿入または移動されたときに更新されます。フェッチされた結果を配列にコピーすることにより、変更があった後で最新の情報を探しています。代わりに(直接fetchedResultsControllerの値で、すなわちアクセスself.taskfetch.fetchedObjectsを見たりself.taskfetch.object(at:indexPath)を使用しています。

あなたはfetchedResultsController(s)はについてあなたに通知されていませんが、というの変化に基づいて、あなたのテーブルビューを更新しているので、これはクラッシュの原因となった理由は、古い古いデータを参照しているため、テーブル内の行数を更新する

もう1つの問題は、いずれかのデータセットが変更されたときにBOTHテーブルを更新することです。行が間違ったテーブルで間違っています。すべてのコントローラメソッドでは、最初にどのコントローラであるかを確認してください。if controller == taskfetch {

+0

私は、データのセットごとに2つの異なるfuncを変更する必要がありますか? –

+0

私はそれに対処するために私の答えを更新しました –

+0

それはありがとう –

関連する問題