Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use `protocol` and `protocol: class` in Swift?

I have setup a protocol to send some information back to the previous VC.

I define it like this:

protocol FilterViewControllerDelegate: class  {
    func didSearch(Parameters:[String: String]?)
}

But what is the difference when using:

protocol FilterViewControllerDelegate  {
        func didSearch(Parameters:[String: String]?)
    }

And when should I use a : class protocol?

like image 330
user2636197 Avatar asked Oct 19 '16 22:10

user2636197


People also ask

Why do we use class and protocol in Swift?

It means that the protocol you define can be adopted only by classes, not structures or enums. In the example above, SomeClassOnlyProtocol can only be adopted by class types. It is a compile-time error to write a structure or enumeration definition that tries to adopt SomeClassOnlyProtocol.

What's the difference between a protocol and a class in Swift?

You can create objects from classes, whereas protocols are just type definitions. Try to think of protocols as being abstract definitions, whereas classes and structs are real things you can create.

What is a protocol in Swift when and how it is used?

In Swift, a protocol defines a blueprint of methods or properties that can then be adopted by classes (or any other types). Here, Greet - name of the protocol. name - a gettable property.

What is Swift protocol class?

Protocol is used to specify particular class type property or instance property. It just specifies the type or instance property alone rather than specifying whether it is a stored or computed property. Also, it is used to specify whether the property is 'gettable' or 'settable'.


3 Answers

Swift 4 version

AnyObject added to a protocol definition like this

protocol FilterViewControllerDelegate: AnyObject  {     func didSearch(parameters:[String: String]?) } 

means that only a class will be able to conform to that protocol.

So given this

protocol FilterViewControllerDelegate: AnyObject  {     func didSearch(parameters:[String: String]?) } 

You will be able to write this

class Foo: FilterViewControllerDelegate {     func didSearch(parameters:[String: String]?) { } } 

but NOT this

struct Foo: FilterViewControllerDelegate {     func didSearch(parameters:[String: String]?) { } } 

Swift 3 version

:class added to a protocol definition like this

protocol FilterViewControllerDelegate: class  {     func didSearch(Parameters:[String: String]?) } 

means that only a class will be able to conform to that protocol.

So given this

protocol FilterViewControllerDelegate: class  {     func didSearch(Parameters:[String: String]?) } 

You will be able to write this

class Foo: FilterViewControllerDelegate {     func didSearch(Parameters:[String: String]?) { } } 

but NOT this

struct Foo: FilterViewControllerDelegate {     func didSearch(Parameters:[String: String]?) { } } 
like image 93
Luca Angeletti Avatar answered Oct 05 '22 23:10

Luca Angeletti


There's also another thing about marking protocols with the class/AnyObject keyword.

Given a protocol like this:

Swift 4 and above (according to docs):

protocol FilterViewControllerDelegate: AnyObject  {
    func didSearch(with parameters: [String: String]?)
}

Pre-Swift 4 syntax:

protocol FilterViewControllerDelegate: class  {
    func didSearch(with parameters: [String: String]?)
}


For example, let's assume that you're creating a DetailViewController with delegate property of FilterViewControllerDelegate type:

class DetailViewController: UIViewController {
    weak var delegate: FilterViewControllerDelegate
}

If you didn't mark that protocol with class keyword, you wouldn't be able to mark that delegate property as a weak one.

Why?

It's simple - only class based properties can have weak relationships. If you're trying to avoid a reference cycle, that's the way to go 😁

like image 38
Rafał M Avatar answered Oct 05 '22 23:10

Rafał M


Swift 5.1, Xcode 11 syntax:

protocol FilterViewControllerDelegate: AnyObject {
       func didSearch(Parameters:[String: String]?)
}

this protocol can be adopted by only classes.

To answer your first question -

But what is the difference when using:

the difference from this:

protocol FilterViewControllerDelegate  {
        func didSearch(Parameters:[String: String]?)
}

is that this protocol can adopt value types, such enums and structs as well.

To answer your second question -

And when should I use a : class protocal?

when you should use class protocol I would like to describe next example from delegate pattern: Imagine that you have delegate protocol.

protocol PopupDelegate: AnyObject {
    func popupValueSelected(value: String)
}

and in another class you want to create a property

var delegate: PopupDelegate?

But this has strong reference that could bring you to problems with memory leaks. One way to fix memory leak is to make delegate property - weak. Until we will not make our protocol only available to apply for classes, Swift thinks we could apply our protocol also to value types.

weak var delegate: PopupDelegate?

If you try to declare your delegate like weak you will see next error:

'weak' var only be applied to class and class-bound protocol types, not 'PopupDelegate'

But we cant apply weak to value types. So we need to restrict our protocol to a reference type, so swift knows that its a reference type. To make you available to declare this delegate as weak you need to restrict your protocol to be used by classes only:

protocol PopupDelegate: AnyObject {
    func popupValueSelected(value: String)
}
like image 40
swift2geek Avatar answered Oct 06 '22 01:10

swift2geek