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 循环中保存最后一个对象的主要内容,如果未能解决你的问题,请参考以下文章