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

Mock CMMotionManager遇属性重写错误:无法用只读属性覆盖可变属性

问题:Mock CMMotionManager时deviceMotionUpdateInterval重写编译错误

我正在为单元测试Mock CMMotionManager,简化后的代码如下:

protocol XMotionManager {
    var isDeviceMotionAvailable: Bool { get }
    var deviceMotionUpdateInterval: TimeInterval { get set }
}

extension CMMotionManager: XMotionManager {}

final class MockCMMotionManager: CMMotionManager {
    private (set) var mockedIsDeviceMotionAvailable = true
    override var isDeviceMotionAvailable: Bool {
        mockedIsDeviceMotionAvailable
    }
    
    private var mockedDeviceMotionUpdateInterval: TimeInterval = 1.0
    override var deviceMotionUpdateInterval: TimeInterval {
        mockedDeviceMotionUpdateInterval
    }
}

协议内容来自API,MockCMMotionManager本应重写这两个属性以便按需设置。其中isDeviceMotionAvailable重写正常,但deviceMotionUpdateInterval出现编译错误:

Cannot override mutable property with read-only property 'deviceMotionUpdateInterval'

我不理解该错误,因为deviceMotionUpdateInterval是var声明的可变属性,并非只读。请问我的代码存在什么问题?


问题原因

你重写的deviceMotionUpdateInterval只实现了getter(只读),但父类CMMotionManager中的这个属性是读写属性(同时支持get和set操作)。Swift的重写规则要求:子类重写父类的属性时,不能缩小其访问权限——不能把读写属性改成只读属性。

看你的代码实现:

private var mockedDeviceMotionUpdateInterval: TimeInterval = 1.0
override var deviceMotionUpdateInterval: TimeInterval {
    mockedDeviceMotionUpdateInterval
}

这段代码本质上只提供了getter的逻辑,没有实现setter,所以编译器判定你把原本的可变属性改成了只读,因此抛出错误。

解决方法

给重写的属性补充setter实现,保持其读写权限即可:

private var mockedDeviceMotionUpdateInterval: TimeInterval = 1.0
override var deviceMotionUpdateInterval: TimeInterval {
    get { mockedDeviceMotionUpdateInterval }
    set { mockedDeviceMotionUpdateInterval = newValue }
}

这样既遵循了父类属性的读写特性,又能通过mockedDeviceMotionUpdateInterval来灵活控制属性值,满足单元测试的Mock需求。

如果希望外部只能通过Mock的方式修改这个值,可以给mockedDeviceMotionUpdateInterval加上private(set)限制,但重写的属性本身必须保留setter:

private(set) var mockedDeviceMotionUpdateInterval: TimeInterval = 1.0
override var deviceMotionUpdateInterval: TimeInterval {
    get { mockedDeviceMotionUpdateInterval }
    set { mockedDeviceMotionUpdateInterval = newValue }
}

内容的提问来源于stack exchange,提问作者Reinhard Männer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 18:35:07