Protocolos solo de clase en Swift


Quiero que algunas de mis clases (no todas) se ajusten usando 'Class-Only Protocols' de docs. Lo que estoy haciendo es

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

Y estoy recibiendo los errores

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

No estoy seguro de que estoy siguiendo exactamente como en los documentos. ¿Alguien tiene alguna idea sobre esto?

Author: Marcus Leon, 2016-07-08

4 answers

Swift 4 le permite combinar tipos, por lo que puede tener su protocolo y luego crear, por ejemplo, un alias de tipo para combinarlo con un requisito de clase específico.

Para (un artificial) ejemplo:

typealias PresentableVC = UIViewController & Presentable

Para el código presentado:

El problema es que estás tratando de limitarte a clases específicas y Swift no puede hacerlo (de todos modos, por el momento). Solo puede limitar a clases y heredar de otros protocolos. Su sintaxis es para la herencia de protocolo, pero usted está tratando de úsalo como una limitación de clase.

Tenga en cuenta que el propósito de los protocolos de clase es:

Use un protocolo solo de clase cuando el comportamiento definido por los requisitos de ese protocolo asume o requiere que un tipo conforme tenga semántica de referencia en lugar de semántica de valor.

 31
Author: Wain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-13 11:56:03

Las respuestas proporcionadas por Chris y Wain son correctos. Solo estoy agregando algunos detalles más aquí.

Definiendo un protocolo

Debe distinguir el concepto de declarar un protocol (disponible para clases)

protocol RefreshData: class {
    func updateController()
}

Definiendo una clase

...del concepto de conformar su clase a un protocolo

class ClassA: RefreshData {
    func updateController() {

    }
}

Conformar una clase que no tienes

A veces se quiere conformar una clase a un protocolo pero no se posee la fuente código para esa clase. En este caso se puede utilizar un extension

extension ClassB: RefreshData {
    func updateController() {

    }
}
 20
Author: Luca Angeletti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-16 09:20:14

La última versión de Swift puede hacerlo! Yo haría un protocolo y extensiones de protocolo que se dirigen a las clases que desea! (restringir la extensión a una clase específica)

    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
        }
}
 8
Author: AMTourky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-23 07:02:40
protocol RefreshData : class
{
    func updateController()
}

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

class ClassB : RefreshData
{
    func updateController() {}
}
 3
Author: Chris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-08 15:47:30