Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Swift符合协议子类_Ios_Swift_Inheritance_Protocols_Subclass - Fatal编程技术网

Ios Swift符合协议子类

Ios Swift符合协议子类,ios,swift,inheritance,protocols,subclass,Ios,Swift,Inheritance,Protocols,Subclass,在我的应用程序中,我有多个依赖于模型的UIView子类。采用“Restorable”协议的每个类,该协议包含模型的超类。每个子模型都描述了特定的UIView而不是通用属性 // Super-model public protocol StoryItem { var id: Int64? { get } } // Parent protocol public protocol Restorable: AnyObject { var storyItem: StoryItem? {

在我的应用程序中,我有多个依赖于模型的UIView子类。采用“
Restorable
”协议的每个类,该协议包含模型的超类。每个子模型都描述了特定的UIView而不是通用属性

// Super-model
public protocol StoryItem {
    var id: Int64? { get }
}

// Parent protocol
public protocol Restorable: AnyObject {
    var storyItem: StoryItem? { get set }
}

// Specific protocol
public struct TextItem: StoryItem {
    public var id: Int64?
    public var text: String?
}

// Not complling
class ResizableLabel: UILabel, Restorable {
    var storyItem: TextItem?
}
我收到以下编译器错误:

*Type 'ResizableLabel' does not conform to protocol 'Restorable'*
我能使其编译的唯一方法是将
resizeblebel
更改为

// Works
class ResizableLabel: UILabel, Restorable {
    var storyItem: StoryItem?
}
是否有任何方法符合协议子类?这将使Init进程更干净。谢谢你的帮助

变化

public protocol Restorable: AnyObject {
    var storyItem: StoryItem? { get set } // adopter must declare as StoryItem
}

现在您的代码可以编译了。完整示例:

public protocol StoryItem {
    var id: Int64? { get }
}
public protocol Restorable: AnyObject {
    associatedtype T : StoryItem
    var storyItem: T? { get set }
}
public struct TextItem: StoryItem {
    public var id: Int64?
    public var text: String?
}
class ResizableLabel: UILabel, Restorable {
    var storyItem: TextItem? // ok because TextItem is a StoryItem adopter
}


嘿@matt,谢谢你的回复。我已经把代码更新得更清楚了。另外,我将TextItem更改为struct而不是protocol。在我的应用程序中,我可以创建标签、图像。贴纸等。它们中的每一个都是使用不同的模型构建的。但是所有的模型都有一个共享公共属性的超类模型。当我向UIView子类添加一个模型时,让我们说label。我想指定此对象从TextModel获取数据(这就是为什么我将storyItem类更改为TextItem。@matt现在,当我创建标签对象时,例如,我创建TextItem,然后将其分配给storyItem(最底层的代码行),每次我想访问它时,我都需要播放它,我试图避免评论,解释你说的话和你想说的话之间的区别。嘿@matt,小的后续问题。假设我有一个UIView,其中有标签、图像、标签作为其他类的子视图。我只想获得在采用'Restorable'子视图时。因此我尝试了如下方法:让restorableSubviews=view.subviews.compactMap({$0as?(Restorable&UIView)})。但我发现编译错误:协议“可恢复”只能用作泛型约束,因为它具有自身或关联的类型要求。| |我需要以不同的方式强制转换它们吗?顺便说一句,如果您认为我需要发布另一个问题,请告诉我,我会立即执行。为了满足您在这个问题上的要求,我们必须进行Restorable一个泛型约束。现在它不能用作类型。最简单的解决方案是声明一个只有Restorable采用的空协议,并将其用作您的类型名(尽管稍后您将不得不放弃).但这不是唯一的解决方案;搜索该错误,您会发现这已经在堆栈溢出上进行了彻底的讨论,因此没有必要再问一个新问题-它将是重复的。感谢您的回答!我应该对每个对象(标签/图像/标签)都这样做吗?还是这是一个协议来管理所有对象?
public protocol StoryItem {
    var id: Int64? { get }
}
public protocol Restorable: AnyObject {
    associatedtype T : StoryItem
    var storyItem: T? { get set }
}
public struct TextItem: StoryItem {
    public var id: Int64?
    public var text: String?
}
class ResizableLabel: UILabel, Restorable {
    var storyItem: TextItem? // ok because TextItem is a StoryItem adopter
}