这是一个简单类别的集合,有助于我经常使用的更新基于数组的UITableView和UICollectionView的常见模式。
它扩展了NSArray,提供了简单的差异功能。您提供初始数组,更新数组,以及一个身份比较块,然后该方法返回包含插入、删除、移动和未移动索引的NSIndexSet的NSDictionary。
为UITableView和UICollectionView提供了类别,它们接受索引集字典,并以批量方式执行行/单元格动画更新。未移动位置的项目可以可选地重新加载。
- (void)updateWithItems:(NSArray *)items {
NSDictionary* indexChangeSets = [NSArray indexChangeSetsForUpdatedList:items
previousList:self.items
identityComparator:^NSComparisonResult(NSDictionary* a, NSDictionary* b) {
// This block should determine if the items in the list have the same identity or not
return [a[@"id"] compare:b[@"id"]];
}];
[self.collectionView performBatchUpdates:^{
self.items = items;
[self.collectionView updateSection:0 withChangeSet:indexChangeSets reloadingUnmoved:YES];
} completion:nil];
}
- (void)updateWithItems:(NSArray *)items {
NSDictionary* indexChangeSets = [NSArray indexChangeSetsForUpdatedList:items
previousList:self.items
identityComparator:^NSComparisonResult(NSDictionary* a, NSDictionary* b) {
// This block should determine if the items in the list have the same identity or not
return [a[@"id"] compare:b[@"id"]];
}];
self.items = items;
[self.tableView beginUpdates];
[self.tableView updateSection:0 withChangeSet:indexChangeSets];
[self.tableView endUpdates];
}
注意:要在此库中用Swift使用,您必须将库头文件导入项目的Bridging Header文件中。
#import "LMArrayChangeSets.h"
有关混合Objective-C和Swift代码的更多详细信息,请参阅此处。
func updateWithItems(items:NSArray) {
let indexChanges = NSArray.indexChangeSetsForUpdatedList(items, previousList: self.items) {
(anyA:AnyObject!, anyB:AnyObject!) -> NSComparisonResult in
let a = anyA as MyObject
let b = anyB as MyObject
// This should determine if the items have the same identity or not
return a.id.compare(b.id)
}
self.collectionView!.performBatchUpdates({
() -> Void in
self.items = items
self.collectionView!.updateSection(0, withChangeSet:indexChanges)
},
completion:nil
)
}
func updateWithItems(items:NSArray) {
let indexChanges = NSArray.indexChangeSetsForUpdatedList(items, previousList: self.items) {
(anyA:AnyObject!, anyB:AnyObject!) -> NSComparisonResult in
let a = anyA as MyObject
let b = anyB as MyObject
// This should determine if the items have the same identity or not
return a.id.compare(b.id)
}
self.items = items
self.tableView!.beginUpdates()
self.tableView!.updateSection(0, withChangeSet:indexChanges, reloadingUnmoved:true)
self.tableView!.endUpdates()
}
请注意:确定更改集使用的算法效率不高。O(N^2)
创建此库时优先考虑开发者效率,而不是原始性能。因此,在大数据集上可能表现不佳。
在我个人的经历中,对于有数百个条目的数据集,性能是完全可接受的。如果您计划在大型数据集上使用此库,请在进行一些性能测试并进行比较例程优化之前先进行测试。
我建议在后台线程上生成更改集。
iOS 6.0+
要运行示例项目,请首先克隆仓库,然后在 Example 目录下运行 pod install
.
cdann, [email protected]
LMArrayChangeSets 在 MIT 许可证下可用。有关更多信息,请参阅 LICENSE 文件。