33

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?

0

4 Answers 4

41

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.

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.

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.

Sign up to request clarification or add additional context in comments.

3 Comments

according to this protocol SomeClassOnlyProtocol: class, SomeInheritedProtocol, what is the meaning of SomeInheritedProtocol after a class, ?. I thought it is a place hoder for class(es)
Some other protocol that this protocol extends
We can't to extend non-nominal type in swift
28

The answers provided by Chris and Wain are correct. I'm just adding a few more details here.

Defining a protocol

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

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 ClassB: RefreshData { func updateController() { } } 

2 Comments

protocol RefreshData: class: dose this expression means that this protocol is available only for classes, Not enums or structs !?
@brahimm Exactly
10

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)

 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 } } 

Comments

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.