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

如何优雅地将UICollectionViewCell/UITableViewCell属性设为只读?

优雅实现UITableViewCell只读属性的方案

嘿,这个场景我太熟悉了!之前做Cell和父VC交互的时候也踩过类似的坑,其实不用搞两个属性那么繁琐,有更简洁的方式来解决,下面给你两种靠谱的方案:

方案一:类扩展重写为readwrite(最推荐)

核心思路是:对外暴露readonly属性,在内部的类扩展里把它改成readwrite,这样编译器就会自动生成带下划线的成员变量_targetMyProductsVC,你就能直接用懒加载的方式实现了。

具体代码实现:

  1. 在.h文件里声明对外的只读属性:
@interface ProductsCell : UITableViewCell
@property (nonatomic, strong, readonly) MyProductsVC *targetMyProductsVC;
@end
  1. 在.m文件的类扩展里重写属性为可写:
@interface ProductsCell ()
// 这里把readonly改成readwrite,内部可以赋值/使用成员变量
@property (nonatomic, strong, readwrite) MyProductsVC *targetMyProductsVC;
@end
  1. 实现你的懒加载getter方法(和你原来的逻辑一样,但现在不会报错了):
- (MyProductsVC *)targetMyProductsVC {
    if (!_targetMyProductsVC) {
        UIResponder *target = self.nextResponder;
        do {
            target = target.nextResponder;
            // 注意:这里要保持类名一致,你代码里的ZBMyProductsVC和MyProductsVC要统一哦
        } while (![target isKindOfClass:MyProductsVC.class] && target != nil);
        _targetMyProductsVC = (MyProductsVC *)target;
    }
    return _targetMyProductsVC;
}

这种方式的好处是:对外完全是只读属性,外部代码无法修改;内部又能正常使用成员变量缓存结果,逻辑清晰又简洁。

方案二:手动合成成员变量(适合老版本编译器)

如果你的项目用的是比较老的Xcode版本,类扩展的方式可能有兼容问题,那可以手动合成成员变量:

在.m文件顶部直接声明成员变量:

@implementation ProductsCell {
    MyProductsVC *_targetMyProductsVC;
}

然后实现getter方法,和你原来的逻辑一样,这样即使属性是readonly,也能直接使用_targetMyProductsVC了。

小提醒:关于responder链的优化

你当前的getter逻辑是对的,第一次找到父VC后就缓存起来,避免每次调用都遍历responder链。不过要注意:如果Cell被复用后,父VC可能发生变化(比如同一个Cell被放到不同的VC里),这时候最好在prepareForReuse方法里清空缓存:

- (void)prepareForReuse {
    [super prepareForReuse];
    _targetMyProductsVC = nil;
}

这样下次调用targetMyProductsVC时会重新遍历responder链,保证拿到的是当前的父VC。

内容的提问来源于stack exchange,提问作者dengApro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:50:55