微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

扩展中的Swift协议类/ AnyObject限制

如何解决扩展中的Swift协议类/ AnyObject限制

我有2个协议,一个给对象一个serverId,另一个给他一个status(又称它是否在服务器上发布)。 他们两个使我能够处理服务器模型和Core Data之间的同步。

/// By conforming to this protocol,classes AND struct have an identifiable serverid `Int64`
protocol RemoteObject {
    var serverId: ServerId { get set }
}

/// This can only be applied to class
protocol Syncable: class {
    var syncStatus: SyncStatus { get set }

}

enum SyncStatus: Int64 {
    case published
    case local
}

其背后的想法是RemoteObject可以应用于结构(即我从服务器返回的 JSON结构)和类(NSManagedobject)。另一方面,Syncable仅可应用于类(NSManagedobject)。

对我来说,下一步是,当syncStatus设置为.local时,我还需要通过将其设置为-1来摆脱对象上RemoteObject上的serverId,但是当我尝试此错误时:

extension Syncable where Self: RemoteObject {
    var syncStatus: SyncStatus {
        get {
            SyncStatus(rawValue: syncStatusValue) ?? .local
        }
        set {
            syncStatusValue = newValue.rawValue
            if newValue == .local { serverId = -1 } // ? Cannot assign to property: 'self' is immutable
        }
    }
}

?无法分配给属性:“自我”是不可变的

我知道我会收到此错误,因为RemoteObject可以应用于不可变的结构。

但是,考虑到Syncable仅可应用于类类型,是否会强制RemoteObject应用于类?然后变得可变了?

是否可以在我的扩展程序中强制RemoteObject成为类类型?例如extension Syncable where Self: RemoteObject & class吗?

解决方法

我终于找到了解决方案。根据这个post,我可以这样做:

extension Syncable where Self: RemoteObject {
    var syncStatus: SyncStatus {
        get {
            SyncStatus(rawValue: syncStatusValue) ?? .local
        }
        set {
            syncStatusValue = newValue.rawValue
            if newValue == .local { 
                var s = self
                s.serverId = -1
            } 
        }
    }
}

这消除了错误,据我所知,对于引用类型的类,这将更改serverId,并且不会使值类型的结构突变(对此协议)。


更进一步,对于谁可能觉得这篇文章有用。我对这个问题的理解不准确。起初,我认为问题出在RemoteObject协议上,该协议可以应用于任何类型。

根据此discussion,问题似乎是另一回事。当限制:class:AnyObject的procotol co时,会强制其setter不变的

然后,当我尝试更改serverId的值时,我从一个不可变调用一个 mutable 设置器,这会导致编译器抱怨。该变通办法很适合我的用法,但是要获得一个适当的解决方案,我应该摆脱:class中的Syncable,并处理所有迫使我使其成为纯类的原因。首先。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。