从核心数据中的实体中删除记录

Posted

技术标签:

【中文标题】从核心数据中的实体中删除记录【英文标题】:Delete a record from an Entity in core data 【发布时间】:2017-06-06 05:56:10 【问题描述】:

我正在 swift 3.0 中开发一个项目,其中我有一个核心数据模块,其中包含一个名为“PlayListDetails”的实体。这包含两个子元素名称 playlistName 和 trackID。因此,每个播放列表名称都有一个 trackID 行间。我的要求是在传递 indexPath.row 时删除特定的元组。虽然我在执行该方法后实现了一个方法,但它给了我一个异常,说“致命错误:索引超出范围”。我的方法如下我保存数据的地方和我用来删除数据的方法。

保存

 public static func savePlaylistDetails(audio:[(title:String,healerName:String,trackUrl:String, trackID:String, imageUrl: String)] = [], playListName: String) 

        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let context = appDelegate.persistentContainer.viewContext
        let newPlaylist = NSEntityDescription.insertNewObject(forEntityName: PlayList_DETAILS_ENTITY, into: context)

        let track = audio.map$0.trackID
        print("Track",track)

        let trackId = track[0]

        print("ID is :",trackId)
        newPlaylist.setValue(playListName, forKey:"playlistName")
        newPlaylist.setValue(trackId, forKey:"trackID")

        do
            try context.save();
            print("Saved.....")
        
        catch
            print("There was an error")
        
    

Delete // 这是我得到异常的地方,我将选定的 rowIndex 传递给函数

func deleteCoreData(rowIndex: Int) 
    let managedContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    var playList = [PlayListDetails] ()
    managedContext.delete(playList[rowIndex]) // this is where the exception throws


    do 
         try managedContext.save()

    catch
        print("fail")
    


我错过了什么??

【问题讨论】:

【参考方案1】:

在核心数据 swift 4 中从实体中删除记录

let appDelegate = UIApplication.shared.delegate as! AppDelegate

let context = appDelegate.persistentContainer.viewContext

let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")

request.predicate = NSPredicate(format: "age = %@ AND username = %@", self.aryOfUsersModel[indexPath.row].value(forKey: "age") as! String,self.aryOfUsersModel[indexPath.row].value(forKey: "username") as! String)

do 
      let result = try context.fetch(request)

      print("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-")
      print("total record aryOfUsersModel \(self.aryOfUsersModel.count)")
      print("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-")

      for data in result as! [NSManagedObject]
      
         context.delete(data)
      
      // fetch all record here after deleting
   

同时更新管理上下文

try context.save()

【讨论】:

【参考方案2】:

如果您尝试删除具有特定索引的项目,我已经提供了在索引处删除项目的解决方案(这可能导致数组超出范围异常),但我建议使用谓词,可以说可能是 id、名称您愿意删除的项目。

我正在根据您的问题提供解决方案, 您可以使用从数据库中获取实体的过程并删除您要删除的特定项目。

请设法添加以下代码,如果要删除某些特定项目,请不要忘记使用谓词

 func deleteCoreData(rowIndex: Int) 

    let managedContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

    do
        //1. Create Request
        let request: NSFetchRequest<PlayListDetails> = PlayListDetails.fetchRequest()

        //Predicate is optional as per need
        //let predicate = NSPredicate(format: "playlistId = %@", id)
        //request.predicate = predicate

        //2. Result object
        let results = try managedObjectcontext.fetch(request as! NSFetchRequest<NSFetchRequestResult>)

        guard results.count > 0 else 
            print("No tems available handle error")
            return
        

        for i in 0...results.count-1 

            if i == rowIndex 
                let theItem = results[index] as NSManagedObject
                managedObjectcontext.delete(item)
            
        
         /*
        for item in results as! [NSManagedObject]
            print(item)
            //hit delete for item you want
            managedObjectcontext.delete(item)
         */

        do 
            try managedObjectcontext.save() // <- remember to put this :)

         catch 
            // Do something... fatalerror
            print("handle error")
            return
        

     catch
        print(error)
        print("handle error")
        return

    
    print("handle error")


更新

“先生,这是我要执行的查询。从 PlayListDetails 中删除所有 trackId=123 和 playlistName= demo 我将如何在上面的代码中实现这一点”

使用谓词

//use predicate for single predicate and compound for multiple predicate 
//Predicate is optional as per need
let predicate = NSPredicate(format: "trackId = %@", id)
let predicate2 = NSPredicate(format: "name = %@", "some name")

//let compoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate, predicate2])

    request.predicate = predicate

在删除部分使用

for item in results as! [NSManagedObject]
                print(item)
                //hit delete for item you want
                managedObjectcontext.delete(item)
             

【讨论】:

这删除了我所有的东西 你必须像我上面提供的那样做谓词(评论),用那个谓词你必须为你想删除哪些项目提供条件! 这是我要执行的查询先生.. 从 PlayListDetails 中删除所有轨道 Id=123 和 playlistName= demo 我将如何在上面的代码中实现这一点

以上是关于从核心数据中的实体中删除记录的主要内容,如果未能解决你的问题,请参考以下文章

在数据迁移期间删除实体中的所有记录

当我删除核心数据实体的最后一条记录时,为啥我的应用程序崩溃了?

删除 CoreData 实体中的所有记录

核心数据:删除最后一个具有一对多关系的实体

在 iOS7 中使用核心数据删除表格视图中的行的奇怪行为

从 Access 数据库中删除不存在的记录