Swift 中的核心数据:仅在 for 循环中保存最后一个对象

Posted

技术标签:

【中文标题】Swift 中的核心数据:仅在 for 循环中保存最后一个对象【英文标题】:Core Data in Swift: Only saving last object in a for loop 【发布时间】:2015-05-22 09:44:35 【问题描述】:

我正在尝试将 Core Data 中的多个对象保存到 for 循环中的 IPodSongs 实体,即当前在 for song in result 循环中的歌曲的标题。但是我的代码只保存了循环中的最后一首歌曲,并且一直覆盖同一个对象。我不需要覆盖同一个对象,而是每次都需要创建一个新对象。我做错了什么?

func fetchiPodSongsOnSignup() 

        var appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

        var context: NSManagedObjectContext = appDel.managedObjectContext!

        var newSong = NSEntityDescription.insertNewObjectForEntityForName("IPodSongs", inManagedObjectContext: context) as! NSManagedObject

        var request = NSFetchRequest(entityName: "IPodSongs")

        request.returnsObjectsAsFaults = false

        var results = context.executeFetchRequest(request, error: nil)


        let query = MPMediaQuery.songsQuery()

        let result = query.collections as! [MPMediaItemCollection]

        for song in result 

            for song in song.items as! [MPMediaItem] 

                newSong.setValue("\(song.valueForProperty(MPMediaItemPropertyTitle))", forKey: "title")

                println(newSong)

                context.save(nil)

            
            

【问题讨论】:

好吧,您创建一个对象var newSong = ....,然后在每次循环迭代中覆盖其属性。解决方案不是很明显吗? 请不要在保存中传递nil。传入一个错误指针并检查错误。总是! 【参考方案1】:

您无需创建请求即可将新对象保存到 Core Data。你做错的是创建一个单独的托管对象,插入它,然后通过循环更改它,而不是为每首歌曲创建一个新对象。

这应该可行:

func fetchiPodSongsOnSignup() 

    var appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

    var context: NSManagedObjectContext = appDel.managedObjectContext!


    let query = MPMediaQuery.songsQuery()

    let result = query.collections as! [MPMediaItemCollection]

    for song in result 

        for song in song.items as! [MPMediaItem] 

            var newSong = NSEntityDescription.insertNewObjectForEntityForName("IPodSongs", inManagedObjectContext: context) as NSManagedObject

            newSong.setValue("\(song.valueForProperty(MPMediaItemPropertyTitle))", forKey: "title")

            println(newSong)


        
    
    if context.save(&errorPointer == false 
        printlin("Error received while saving")
    


还要在最后加上if context.save(&errorPointer == false printlin("Error received while saving")

【讨论】:

当然你的意思是把if context.save(&errorPointer == false printlin("Error received)放在最后对吧? :) 是的,但是查询者似乎不在乎保存上下文是否有错误... 或未受过教育。教育他们错误至关重要的绝佳机会。传递 nil 的示例会导致对其价值的无知。 谢谢大家。我是 Swift 的新手(一般只学了一个月的编程时间),所以我很感谢你的帮助。最后一个 if context.save 方法缺少括号。如果我把它放在false 之后,我会得到一个未解析的标识符errorPointer @MarcusS.Zarra 我可以得到这个errorPointer的确认吗?我仍然收到缺少括号的错误。【参考方案2】:

试试这个,这会奏效....

插入for循环并保存在外部循环中......

func fetchiPodSongsOnSignup() 

var appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

var context: NSManagedObjectContext = appDel.managedObjectContext!


let query = MPMediaQuery.songsQuery()

let result = query.collections as! [MPMediaItemCollection]

for song in result 

    for song in song.items as! [MPMediaItem] 

        var newSong = NSEntityDescription.insertNewObjectForEntityForName("IPodSongs", inManagedObjectContext: context) as NSManagedObject

        newSong.setValue("\(song.valueForProperty(MPMediaItemPropertyTitle))", forKey: "title")

        context.insert(newSong)

    

context.save(nil)

【讨论】:

【参考方案3】:

您在所有迭代中都使用相同的插入对象:

for song in song.items as! [MPMediaItem] 
      newSong.setValue("\(song.valueForProperty(MPMediaItemPropertyTitle))", forKey: "title")

您确实在更改歌曲的对象值,但您使用的是同一个实例,而该实例又是核心数据库中的同一个实体。

您需要为每首新歌使用一个新实例:

 var newSong = NSEntityDescription.insertNewObjectForEntityForName("IPodSongs", inManagedObjectContext: context) as! NSManagedObject
 newSong.setValue("\(song.valueForProperty(MPMediaItemPropertyTitle))", forKey: "title")

【讨论】:

【参考方案4】:

这很可能对你有用!试试吧!

for song in result 

        for song in song.items as! [MPMediaItem] 
            var newSong = NSEntityDescription.insertNewObjectForEntityForName("IPodSongs", inManagedObjectContext: context) as! NSManagedObject
            newSong.setValue("\(song.valueForProperty(MPMediaItemPropertyTitle))", forKey: "title")

            println(newSong)

            context.save(nil)

        
       

【讨论】:

以上是关于Swift 中的核心数据:仅在 for 循环中保存最后一个对象的主要内容,如果未能解决你的问题,请参考以下文章

如何在后台线程swift中运行for循环

swift核心数据:保存相机中的图像

如何在swift中保存核心数据中的值

使用 NSPredicate 对表视图中的核心数据进行排序 (Swift)

Swift 3 中的 JSON 图像和核心数据 [关闭]

Swift中的Loop for Loop总和