Swift:如何优雅标记父类属性Getter/Setter为不可用且允许内部调用?
优化方案:隐藏SKSpriteNode的color属性
现有代码痛点
你当前的实现存在两个核心问题:
- 为了禁用外部访问
color属性,必须完整实现重写的Getter/Setter,代码冗余繁琐 - 类内部无法直接使用
self.color,只能通过super.color访问,降低了代码可读性
优化后的实现
public final class MyAdaptiveSprite: SKSpriteNode { private let textureColor: AdaptiveColor public init(texture: SKTexture, size: CGSize, color: AdaptiveColor) { textureColor = color super.init(texture: texture, color: .clear, size: size) adaptThemeChange() } // 标记外部不可用,并给出明确的替代方案提示 @available(*, unavailable, message: "请使用adaptThemeChange()方法管理颜色") public override var color: UIColor { get { super.color } set { super.color = newValue } } // 内部便捷访问的私有别名,避免重复书写super.color private var internalColor: UIColor { get { super.color } set { super.color = newValue } } public func adaptThemeChange() { internalColor = textureColor.lightModeOrDarkModeColor } // 补充实现required初始化方法,避免编译报错 @available(*, unavailable) required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
关键优化点
- 友好的不可用提示:给
@available添加message参数,外部调用color时编译器会直接提示正确的API用法,比单纯标记不可用更直观 - 内部便捷访问:新增私有
internalColor属性,类内部可以直接用这个别名操作父类的color,不用反复写super.color,代码更简洁 - 合规的重写实现:重写的
color属性依然调用父类的实现,既满足super.init的调用要求(避免崩溃),又完全屏蔽了外部的访问路径
关于“仅外部不可用”的补充
Swift目前没有原生修饰符可以让属性对外部不可用但内部可用,但通过「外部标记不可用+内部私有别名」的组合方式,可以间接实现这个需求,既满足外部API隐藏的要求,又不影响内部代码的可读性。
内容的提问来源于stack exchange,提问作者OMGPOP
相关产品推荐
相关产品推荐

