协议扩展初始化器 [英] Protocol Extension Initializer

查看:108
本文介绍了协议扩展初始化器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道在一个仅包含初始化功能并且仅打算在具体类中进行扩展的简单类中,对于初始化程序而言,等效协议是什么.

I would like to know what the protocol equivalent is for an initializer in a simple class that only contains initializing functionality and is only intended to be extended in a concrete class.

因此,最简单的方法可能是显示代码-我正在寻找与以下内容等效的协议扩展:

So probably the easiest is to show the code - I'm looking for the protocol extension equivalent of the following:

import UIKit

class Thing {
    var color:UIColor
    init(color:UIColor) {
        self.color = color
    }
}
class NamedThing:Thing {
    var name:String
    init(name:String,color:UIColor) {
        self.name = name
        super.init(color:color)
    }
}
var namedThing = NamedThing(name: "thing", color: UIColor.blueColor())

我希望代码看起来像这样:

I was expecting the code to look something like:

protocol Thing {
    var color:UIColor {get set}
}
extension Thing {
    init(color:UIColor) {
        self.color = color
    }
}
class NamedThing:Thing {
    var name:String
    var color:UIColor
    init(name:String,color:UIColor) {
        self.name = name
        self.init(color:color)
    }
}

我已经看到其他StackOverflow问题中建议的解决方案(例如如何在协议扩展中定义初始值设定项?),但我不确定它们是否起作用,也不确定在类初始值设定项中专门解决此附加参数问题.

I've seen solutions suggested in other StackOverflow questions(eg. How to define initializers in a protocol extension?) but I'm not sure they work nor specifically address this problem of additional parameters in the class initializer.

推荐答案

您必须提供有效的初始化链来创建类的实例,并且限制了协议中初始化程序的选择.

You have to provide a valid chain of init for creating an instance of a class and that limits your options for initializers in protocols.

由于不能确定协议是否涵盖使用该协议的类的所有成员,因此您在协议中声明的任何初始化程序都需要将该类未知"成员的初始化委派给该类提供的另一个初始化程序本身.

Since your protocol can't be certain to cover all members of the class that uses it, any initializer you declare in your protocol will need to delegate initialization of the "unknown" members of the class to another initializer provided by the class itself.

我调整了您的示例,以使用基本的init()作为协议的委托初始化程序进行说明.

I adjusted your example to illustrate this using a basic init() as the delegation initializer for the protocol.

如您所见,这要求您的类在调用init()时为所有成员实现初始值.在这种情况下,我通过在每个成员的声明中提供默认值来做到这一点.而且,由于某些成员并不总是有实际的初始值,因此我将其更改为自动展开可选对象.

As you can see, this requires that your class implement initial values for all members when init() is called. In this case I did that by providing default values in each member's declaration. And, since there isn't always an actual initial value for some members, I changed them to auto-unwrap optionals.

为了使您的想法更有趣,您的类不能将初始化委派给协议提供的初始化程序,除非它通过便捷的初始化程序进行初始化.

And to make thinks more interesting, your class cannot delegate initialization to a protocol supplied initializer unless it does so through a convenience initializer.

我想知道所有这些限制是否值得解决.我怀疑您正在尝试使用协议,因为您需要在实现该协议的类之间一致地初始化一堆公共变量.也许使用委托类将提供比协议少花时间的解决方案(只是一个想法).

I wonder if all these restrictions are worth the trouble. I suspect you're trying to use a protocol because you need a bunch of common variables to be initialized consistently between classes that implement the protocol. Perhaps using a delegate class would provide a less convoluted solution than protocols (just a thought).

protocol Thing:AnyObject
{
    var color:UIColor! { get set }
    init()
}

extension Thing 
{    
    init(color:UIColor)
    {  
       self.init()
       self.color = color
    }
}

class NamedThing:Thing 
{
    var name:String!   = nil
    var color:UIColor! = nil

    required init() {}

    convenience init(name:String,color:UIColor) 
    {
        self.init(color:color)
        self.name = name
    }
}

这篇关于协议扩展初始化器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆