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

Swift子类调用超类初始化器因private权限报错的解决方法

子类化SwiftySound的Sound类时的访问权限问题

问题说明

基于SwiftySound框架的Sound类创建子类SoundWrapper,要求添加imageName字符串属性并实现Hashable协议。编写初始化器时调用super.init(url: url)出现错误:'url' is inaccessible due to 'private' protection level,同时初始化器的设计与实际调用需求不匹配。

现有代码

子类代码

class SoundWrapper:Sound, Hashable{
    let id = UUID()
    let imageName : String
    
    init(imageName: String) {
           self.imageName = imageName
           super.init(url: url)
// Error: 'url' is inaccessible due to 'private' protection level
       }
    
    
    public func hash(into hasher: inout Hasher) {
            hasher.combine(0)
        }
    
    static func == (lhs: SoundWrapper, rhs: SoundWrapper) -> Bool {
        return lhs.id == rhs.id
    }
    
}

计划初始化方式

let backgroundAudio1 = SoundWrapper(imageName: "image1", url: getFileUrl(name: "backgroundAudio1"))

获取URL的方法

func getFileUrl (name: String) -> URL {
    let filePath = Bundle.main.path(forResource: name, ofType: "wav")!
    return URL(fileURLWithPath: filePath)
}

SwiftySound框架的Sound类核心初始化逻辑

open class Sound {
    // ... 其他代码省略 ...
    
    /// Create a sound object.
    ///
    /// - Parameter url: Sound file URL.
    public init?(url: URL) {
        // ... 初始化逻辑 ...
    }
    
    // ... 其他代码省略 ...
}

解决方案

修改后的子类代码

class SoundWrapper: Sound, Hashable {
    let id = UUID()
    let imageName: String
    // 可选:自行存储URL,因为Sound类未暴露该属性
    private let soundUrl: URL

    // 声明为可失败初始化器,匹配超类的init?(url:)
    init?(imageName: String, url: URL) {
        self.imageName = imageName
        self.soundUrl = url
        // 传入外部传入的URL调用超类初始化器
        super.init(url: url)
    }

    public func hash(into hasher: inout Hasher) {
        // 使用id生成哈希值,保证唯一性
        hasher.combine(id)
    }

    static func == (lhs: SoundWrapper, rhs: SoundWrapper) -> Bool {
        return lhs.id == rhs.id
    }
}

正确初始化调用

if let backgroundAudio1 = SoundWrapper(imageName: "image1", url: getFileUrl(name: "backgroundAudio1")) {
    // 初始化成功,使用SoundWrapper实例
}

错误原因与解释

  1. 初始化器参数不匹配:原子类初始化器仅接收imageName,但实际调用需要传入url,导致代码中super.init(url: url)的url未定义,直接引发错误。
  2. 超类初始化器特性:Sound类的初始化器是可失败初始化器(init?),子类必须使用相同的可失败语义,否则无法编译通过。
  3. 属性访问权限:Sound类未将初始化时传入的url作为公共属性存储,因此子类无法直接访问超类内部的url变量,必须从外部传入该参数。
  4. Hashable实现优化:原代码中hasher.combine(0)会导致所有实例的哈希值相同,不符合Hashable协议的预期,改为结合id可保证哈希值的唯一性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 19:35:27