如何解决扩展中的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 举报,一经查实,本站将立刻删除。