Swift Cannot assign to value: 'self' is immutable 解决方案

我们想在遍历初始化器中使用self=???的时候会报以下错误

 Cannot assign to value: 'self' is immutable  
举例:
我们想要加载本地库的UIImage的时候能够很方便的加载,那么想要给UIImage添加一个方法以便利使用
extension UIImage {
    public convenience init?(named name: String, inCls class: AnyClass) {

        guard let bundlePath = Bundle(for: `class`).paths(forResourcesOfType: "bundle", inDirectory: nil).first else {
            return nil
        }
        
        self = UIImage(named: name, in: Bundle(path: bundlePath), compatibleWith: nil) as! Self
    }
}

这样之后是编译不过的, 会在self = UIImage(named: name, in: B....发生Cannot assign to value: 'self' is immutable报错

解释

首先,请注意此限制仅适用于classes,在structs 和enums中修改自身加上关键字mutating以后就能够了

这种对class初始化器的限制是一个经常出现在这个站点上的痛点(例如)。在 Swift 论坛上有一个线程讨论这个问题,并且已经开始添加必要的语言特性来编译上面的示例代码,但这在 Swift 5.4 中还没有完成。从线程:

Swift 自己的标准库和 Foundation 覆盖层通过使类符合虚拟协议并在必要时使用协议扩展初始化器来实现此功能来绕过此缺失的功能。

解决方案

使用协议扩展初始化器解决
public protocol ResourceLoadProtocol  {
    
}

extension UIImage : ResourceLoadProtocol {
    
}

extension ResourceLoadProtocol {
    
    public init?(named name: String, inCls class: AnyClass) {
        let resourceBundlePath = Bundle(for: `class`).paths(forResourcesOfType: "bundle", inDirectory: nil).first
        
        self = UIImage(named: name, in: Bundle(path: resourceBundlePath!), compatibleWith: nil) as! Self
    }
    
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容