如果播放列表计数 = 0,应用程序崩溃(空播放列表是否有 persistentid?)
App crashes if playlist count = 0 (Do empty playlists have a persistentid?)
如果播放列表为空(没有歌曲),我的应用程序就会崩溃。我的应用适用于所有非空播放列表。似乎没有空播放列表的 persistentid,但我认为我错了。
let qryPlaylists = MPMediaQuery.playlistsQuery()
var selectedPlaylistTitle: String!
var selectedPlaylistPersistentID: UInt64!
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let indexPath: NSIndexPath = playlistsTableView.indexPathForSelectedRow!
let rowItem = qryPlaylists.collections![indexPath.row]
let playlistSize = rowItem.count
print("playlistSize = ", playlistSize)
selectedPlaylistTitle = rowItem.valueForProperty(MPMediaPlaylistPropertyName) as! String
print("selectedPlaylistTitle = ", selectedPlaylistTitle)
// Will crash on this next line if the playlistSize = 0
selectedPlaylistPersistentID = rowItem.items[0].persistentID
// If I use following line instead, it will crash on any playlist
// selectedPlaylistPersistentID = rowItem.valueForProperty(MPMediaPlaylistPropertyPersistentID) as! UInt64
// This line will never be printed
print("selectedPlaylistPersistentID = ", selectedPlaylistPersistentID)
}
在此先感谢您的帮助!
如果 items
这样的数组是空的,它没有索引 0
并且如果你引用它会崩溃,并出现 out-of-bounds 错误。所以如果你不想崩溃,就不要那样做。你已经知道 items
是空的,因为 rowItem.count
告诉你了;正如您自己所说,playlistSize
在这种情况下为 0。
一种simple-minded的看待方式是这样的:数组中最大的合法索引比它的count
少。
您询问的另一个问题是这条线总是崩溃:
selectedPlaylistPersistentID = rowItem.valueForProperty(MPMediaPlaylistPropertyPersistentID) as! UInt64
这里的问题是您显然在使用 Swift 2.x。 (你应该在你的问题中这么说;不过,我是从 valueForProperty
没有更改为 value(forProperty:)
的事实推断出来的,这就是 Swift 3 中的名称。)
在Swift2中,不能直接向下转换为UInt64。 (令我惊讶的是,编译器没有通过警告提醒您注意这一事实。)因此,转换失败,您崩溃了。您需要向下转换为 NSNumber,然后取该 NSNumber 的 unsignedLongLongValue
.
在执行此操作时,您真的应该停止在代码中使用感叹号。当我说 "cast down" 时,我的意思是 "cast down safely"。我自己的 Swift 2 执行此类操作的代码如下所示:
if let id = (rowItem.valueForProperty(MPMediaItemPropertyAlbumPersistentID) as? NSNumber)?.unsignedLongLongValue {
// ...
}
如果播放列表为空(没有歌曲),我的应用程序就会崩溃。我的应用适用于所有非空播放列表。似乎没有空播放列表的 persistentid,但我认为我错了。
let qryPlaylists = MPMediaQuery.playlistsQuery()
var selectedPlaylistTitle: String!
var selectedPlaylistPersistentID: UInt64!
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let indexPath: NSIndexPath = playlistsTableView.indexPathForSelectedRow!
let rowItem = qryPlaylists.collections![indexPath.row]
let playlistSize = rowItem.count
print("playlistSize = ", playlistSize)
selectedPlaylistTitle = rowItem.valueForProperty(MPMediaPlaylistPropertyName) as! String
print("selectedPlaylistTitle = ", selectedPlaylistTitle)
// Will crash on this next line if the playlistSize = 0
selectedPlaylistPersistentID = rowItem.items[0].persistentID
// If I use following line instead, it will crash on any playlist
// selectedPlaylistPersistentID = rowItem.valueForProperty(MPMediaPlaylistPropertyPersistentID) as! UInt64
// This line will never be printed
print("selectedPlaylistPersistentID = ", selectedPlaylistPersistentID)
}
在此先感谢您的帮助!
如果 items
这样的数组是空的,它没有索引 0
并且如果你引用它会崩溃,并出现 out-of-bounds 错误。所以如果你不想崩溃,就不要那样做。你已经知道 items
是空的,因为 rowItem.count
告诉你了;正如您自己所说,playlistSize
在这种情况下为 0。
一种simple-minded的看待方式是这样的:数组中最大的合法索引比它的count
少。
您询问的另一个问题是这条线总是崩溃:
selectedPlaylistPersistentID = rowItem.valueForProperty(MPMediaPlaylistPropertyPersistentID) as! UInt64
这里的问题是您显然在使用 Swift 2.x。 (你应该在你的问题中这么说;不过,我是从 valueForProperty
没有更改为 value(forProperty:)
的事实推断出来的,这就是 Swift 3 中的名称。)
在Swift2中,不能直接向下转换为UInt64。 (令我惊讶的是,编译器没有通过警告提醒您注意这一事实。)因此,转换失败,您崩溃了。您需要向下转换为 NSNumber,然后取该 NSNumber 的 unsignedLongLongValue
.
在执行此操作时,您真的应该停止在代码中使用感叹号。当我说 "cast down" 时,我的意思是 "cast down safely"。我自己的 Swift 2 执行此类操作的代码如下所示:
if let id = (rowItem.valueForProperty(MPMediaItemPropertyAlbumPersistentID) as? NSNumber)?.unsignedLongLongValue {
// ...
}