ios Swift 中的 Class-Only 协议

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38270635/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 09:39:10  来源:igfitidea点击:

Class-Only Protocols in Swift

iosswiftswift2protocolsconform

提问by tonytran

I want some of my classes (not all) to conform using 'Class-Only Protocols'from docs. What I am doing is

我希望我的一些类(不是全部)使用文档中的“仅限类的协议”。我正在做的是

protocol RefreshData: class, ClassA, ClassB
{
    func updateController()
}

and I am getting the errors

我收到了错误

non class type 'RefreshData cannot inherit from classA
non class type 'RefreshData cannot inherit from classB

I'm not sure I am following exactly as in the docs. Does anyone have any ideas about this?

我不确定我是否完全按照文档中的说明进行操作。有没有人对此有任何想法?

回答by Wain

Swift 4 allows you to combine types, so you can have your protocol and then create, for example, a type alias to combine it with a specific class requirement.

Swift 4 允许您组合类型,因此您可以拥有自己的协议,然后创建例如类型别名以将其与特定的类要求组合。

For (a contrived) example:

对于(人为的)示例:

typealias PresentableVC = UIViewController & Presentable


For the presented code:

对于提供的代码:

The problem is that you're trying to limit to specific classes and Swift can't do that (at the moment anyway). You can only limit to classes and inherit from other protocols. Your syntax is for protocol inheritance but you're trying to use it as a class limitation.

问题是你试图限制到特定的类,而 Swift 不能这样做(目前无论如何)。您只能限制为类并从其他协议继承。您的语法用于协议继承,但您试图将其用作类限制。

Note that the purpose of class protocols is:

请注意,类协议的目的是:

Use a class-only protocol when the behavior defined by that protocol's requirements assumes or requires that a conforming type has reference semantics rather than value semantics.

当该协议的要求定义的行为假定或要求符合类型具有引用语义而不是值语义时,使用仅类协议。

回答by Luca Angeletti

The answers provided by Chrisand Wainare correct. I'm just adding a few more details here.

ChrisWain提供的答案是正确的。我只是在这里添加更多细节。

Defining a protocol

定义协议

You must distinguish the concept of declaring a protocol(available for classes)

您必须区分声明 a 的概念protocol(可用于类)

protocol RefreshData: class {
    func updateController()
}

Defining a class

定义一个类

...from the concept of conforming your class to a protocol

...从使您的类符合协议的概念

class ClassA: RefreshData {
    func updateController() {

    }
}

Conforming a class you don't own

符合您不拥有的课程

Sometimes you want to conform a class to a protocol but you don't own the source code for that class. In this case you can use an extension

有时您希望使类符合协议,但您不拥有该类的源代码。在这种情况下,您可以使用extension

extension ClassB: RefreshData {
    func updateController() {

    }
}

回答by AMTourky

Latest version of Swift can do it! I would do a protocol and protocol extensions that target the classes you want! (constraint the extension to specific class)

最新版本的 Swift 可以做到!我会做一个针对你想要的类的协议和协议扩展!(将扩展限制为特定类)

    protocol Movable {
        func moveForward()
        func moveBackward()
    }

    extension Movable where Self: Car {
        func moveForward() {
            self.location.x += 10;
        }

        func moveBackward() {
            self.location.x -= 10;
        }
    }
    extension Movable where Self: Bike {
        func moveForward() {
            self.x += 1;
        }

        func moveBackward() {
            self.x -= 1;
        }
    }

    class Car: Movable {
        var location: CGPoint

        init(atLocation location: CGPoint) {
            self.location = location
        }
    }

    class Bike: Movable {
        var x: Int

        init(atX x: Int) {
            self.x = x
        }
}

回答by Chris

protocol RefreshData : class
{
    func updateController()
}

class ClassA : RefreshData
{
    func updateController() {}
}

class ClassB : RefreshData
{
    func updateController() {}
}