Objective-C实现UICollectionViewDiffableDataSource的模型需满足哪些要求
解答
核心要求
Objective-C 中使用 UICollectionViewDiffableDataSource 时,你的自定义 item 类型不需要遵循特殊的命名协议,但是必须满足3个核心要求,对应Swift中Hashable和Identifiable的能力:
- 配对实现
-isEqual:和-hash方法:这是Diffable数据源判断两个item是否为同一个业务条目的核心依据,两个方法必须配对,保证isEqual:返回YES的两个实例,hash值一定相等。 - 遵循
NSCopying协议,实现-copyWithZone:方法:Diffable数据源的快照会拷贝item对象作为唯一标识符存储,因此必须支持拷贝。
你提到的-compare:方法完全不需要,Diffable数据源不要求排序能力,条目顺序完全由你构造快照时的顺序决定。
代码实现示例
头文件修改(MyItemType.h)
@interface MyItemType : NSObject <NSCopying> // 新增遵循NSCopying协议 @property (strong, nonatomic) NSString *title; @property (strong, nonatomic, nullable) NSString *subtitle; @property (strong, nonatomic, nullable) NSArray<MyItemType *> *children; @property (strong, nonatomic, nullable) UIImage *image; // 可选优化:建议新增唯一业务ID属性(比如后台返回的条目ID),作为判等的核心依据,避免重复title导致的判断错误 // @property (strong, nonatomic) NSString *itemId; @end
实现文件修改(MyItemType.m)
@implementation MyItemType - (BOOL)isEqual:(id)object { if (self == object) return YES; if (![object isKindOfClass:[MyItemType class]]) return NO; MyItemType *other = (MyItemType *)object; // 如果你有itemId,直接判断itemId相等即可 // return [self.itemId isEqual:other.itemId]; // 没有itemId的话,用能唯一标识条目的属性组合判断 BOOL titleEqual = self.title && other.title ? [self.title isEqual:other.title] : self.title == other.title; BOOL subtitleEqual = self.subtitle && other.subtitle ? [self.subtitle isEqual:other.subtitle] : self.subtitle == other.subtitle; return titleEqual && subtitleEqual; // 注意:如果你希望条目内容变化时Diffable自动检测到刷新,就把所有参与UI展示的属性都加入判等逻辑 } - (NSUInteger)hash { // 判等用到了哪些属性,hash就用这些属性的hash组合 // 如果有itemId直接返回self.itemId.hash即可 return self.title.hash ^ self.subtitle.hash; } - (id)copyWithZone:(NSZone *)zone { MyItemType *copy = [[MyItemType allocWithZone:zone] init]; copy.title = self.title; copy.subtitle = self.subtitle; copy.children = self.children; // 如果需要深拷贝可以自行修改 copy.image = self.image; // copy.itemId = self.itemId; return copy; } @end
补充说明
如果你的条目内容会动态更新,建议拆分「唯一标识符」和「模型数据」:用NSString类型的唯一ID作为Diffable的item标识符,单独存储模型数组,这样即使模型内容变化,ID不变也能正确识别为同一个条目,你只需要在更新数据后重新构造快照应用即可。
内容的提问来源于stack exchange,提问作者ashipma
相关产品推荐
相关产品推荐

