DiffableDataSource引发“致命:提供的标识符不是唯一的。”将MPMediaItem包装在结构中时
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DiffableDataSource引发“致命:提供的标识符不是唯一的。”将MPMediaItem包装在结构中时相关的知识,希望对你有一定的参考价值。
我用UITableviewDiffableDataSource
和UITableView
来显示音乐库中的歌曲。这段代码运行良好:
let tracks: [MPMediaItem] = MPMediaQuery.songs().items ?? []
self.dataSource.apply(section: 0, items: tracks)
但是当我将MPMediaItem
包装在自定义Track struct
中时,出现此错误:Fatal: supplied identifiers are not unique.
struct Track: Equatable, Hashable
let item: MPMediaItem
var title: String? item.title
init(item: MPMediaItem)
self.item = item
let items = MPMediaQuery.songs().items ?? []
let tracks: [Track] = items.map Track(item: $0)
self.dataSource.apply(section: 0, items: tracks)
[MPMediaItem
已经符合Equatable
和Hashable
,所以我认为如果我在也符合Equatable
和Hashable
(Track struct
)的其他结构中使用它应该没问题。
更新1:apply(section:items:)
是我为方便起见添加到UITableViewDiffableDataSource
的扩展名:
extension UITableViewDiffableDataSource
func apply(section: SectionIdentifierType, items: [ItemIdentifierType], animatingDifferences: Bool = false)
var snapshot = NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>()
snapshot.appendSections([section])
snapshot.appendItems(items)
apply(snapshot, animatingDifferences: animatingDifferences)
更新2:在我使Track
符合Identifiable
协议后,它起作用了:
struct Track: Equatable, Hashable, Identifiable
let item: MPMediaItem
let id: MPMediaEntityPersistentID
var title: String? item.title
init(item: MPMediaItem)
self.item = item
self.id = item.persistentID
甚至更改为存储属性的title
都没有任何错误:
struct Track: Equatable, Hashable
let item: MPMediaItem
let title: String?
init(item: MPMediaItem)
self.item = item
self.title = item.title
这些情况之间有何不同?当使用MPMediaItem
作为Track
结构的唯一存储属性时,为什么会出现错误?预先感谢!
我将猜测MPMediaItem的哈希性存在错误。对于上述两种情况,这可能会导致您获得不同的答案。在此示例中,我将故意制造一个有问题的NSObject:
class Dog : NSObject
let name : String?
init(name:String?) self.name = name
override func isEqual(_ object: Any?) -> Bool
if let dog = object as? Dog
return self.name == dog.name
return false
struct DogHolder : Hashable
let dog : Dog
var name : String? dog.name
这里是测试:
var set = Set<DogHolder>()
let dh1 = DogHolder(dog:Dog(name:"rover"))
let dh2 = DogHolder(dog:Dog(name:"rover"))
set.insert(dh1)
set.insert(dh2)
print(set.count)
do
var set = Set<Dog>()
let dh1 = Dog(name:"rover")
let dh2 = Dog(name:"rover")
set.insert(dh1)
set.insert(dh2)
print(set.count)
一遍又一遍地运行测试。有时我得到1和2。有时我得到2和1。有时我得到1和1。有时我崩溃了。
我不知道确切的问题是什么,但是显然将NSObject散列性暴露给Swift的散列性要求暴露了这个错误。我建议将此情况报告给Apple,同时继续使用替代方法,例如您的标识符。
以上是关于DiffableDataSource引发“致命:提供的标识符不是唯一的。”将MPMediaItem包装在结构中时的主要内容,如果未能解决你的问题,请参考以下文章
DiffableDataSource - 无动画,但在删除操作期间闪烁
UICollectionViewController + diffableDataSource - 当您的手指仍在其上时,单元格不会突出显示
DiffableDataSource CollectionView 在部分中不返回任何项目