You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Objective-C实现UICollectionViewDiffableDataSource的模型需满足哪些要求

解答

核心要求

Objective-C 中使用 UICollectionViewDiffableDataSource 时,你的自定义 item 类型不需要遵循特殊的命名协议,但是必须满足3个核心要求,对应Swift中Hashable和Identifiable的能力:

  1. 配对实现-isEqual:和-hash方法:这是Diffable数据源判断两个item是否为同一个业务条目的核心依据,两个方法必须配对,保证isEqual:返回YES的两个实例,hash值一定相等。
  2. 遵循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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 17:45:08