【问题标题】:Core Data in Swift: Only saving last object in a for loopSwift 中的核心数据:仅在 for 循环中保存最后一个对象
【发布时间】:2015-08-04 06:49:17
【问题描述】:

我正在尝试将 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。传入一个错误指针并检查错误。总是!

标签: ios swift for-loop core-data


【解决方案1】:

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

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)

        }
    }   

【讨论】:

    【解决方案2】:

    您无需创建请求即可将新对象保存到 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的确认吗?我仍然收到缺少括号的错误。
    【解决方案3】:

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

    插入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)
    }
    

    【讨论】:

      【解决方案4】:

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

      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")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-07-04
        • 2011-09-20
        • 2017-03-31
        • 1970-01-01
        • 2015-06-02
        • 1970-01-01
        相关资源
        最近更新 更多