Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protocol inheritance + delegates in Swift

Tags:

ios

swift

I have a class with a delegate. I create a subclass, which also has a delegate. I wanted to let the protocol used for the second delegate extend the protocol used for first delegate:

protocol MySuperClassProtocol {
    func foo()
}

class MySuperClass {
    var delegate:MySuperClassProtocol?
}

protocol MySubClassProtocol:MySuperClassProtocol {
    func bar()
}

class MySubClass: MySuperClass {
    override var delegate:MySubClassProtocol? // compiler error - "cannot override..."

    func test() {
        delegate?.foo()
        delegate?.bar()
    }
}

class UserClass:MySubClassProtocol {
    func foo() {
        println("foo!")
    }
    func bar() {
        println("bar")
    }
} 

Is there a way to solve this? The only possible solution I see is to make the 2 protocols independent of each other, and use different names. Like this:

protocol MySuperClassProtocol {
    func foo()
}

class MySuperClass {
    var mySuperClassDelegate:MySuperClassProtocol?
}

protocol MySubClassProtocol {
    func bar()
}

class MySubClass: MySuperClass {
    var mySubClassDelegate:MySubClassProtocol?

    func test() {
        mySuperClassDelegate?.foo()
        mySubClassDelegate?.bar()
    }
}

class UserClass:MySuperClassProtocol, MySubClassProtocol {
    func foo() {
        println("foo!")
    }
    func bar() {
        println("bar")
    }
}

But this looks a bit weird + will not let me use naming convention for delegate- "delegate".

like image 599
User Avatar asked Mar 15 '15 08:03

User


People also ask

What are protocols and delegates in Swift?

In Swift, declaring a delegate property is just like declaring any other property and you specify the protocol name as the type of the property. You may notice the question mark syntax which indicates that it's a property with an optional value (there may or may not be an object assigned to it).

What is difference between protocol and delegate in Swift?

Protocol is a set of methods (either optional or required) that would be implemented by the class which conforms to that protocol. While, delegate is the reference to that class which conforms to that protocol and will adhere to implement methods defined in protocol.

What is protocol inheritance in Swift?

One protocol can inherit from another in a process known as protocol inheritance. Unlike with classes, you can inherit from multiple protocols at the same time before you add your own customizations on top. Now we can make new types conform to that single protocol rather than each of the three individual ones.

What are delegates used for in Swift?

Delegates are a design pattern that allows one object to send messages to another object when a specific event happens. Imagine an object A calls an object B to perform an action.


1 Answers

I was trying to find an ideal solution to this for some time, but could not come up with anything better that this:

protocol BaseDelegateProtocol: class { }

class BaseDelegate: BaseDelegateProtocol { }

class BaseActor {
    weak var delegate: BaseDelegate? = nil
}

// MARK: -

protocol ConcreteDelegateProtocol: class {
    func doSomething()
}

class ConcreteDelegate: BaseDelegate, ConcreteDelegateProtocol {
    func doSomething() {
        // Do something
    }
}

class ConcreteActor: BaseActor {
    private weak var concreteDelegate: ConcreteDelegateProtocol? = nil

    override var delegate: BaseDelegate? {
        didSet {
            concreteDelegate = delegate as? ConcreteDelegateProtocol
        }
    }
}

Above works in XCode 7 / Swift 2.

  • This pattern allows adopting more and more protocols on the way down inheriting from BaseDelegate.
  • There is no need to inherit protocols one from the other, which helps keeping things isolated.
  • didSet observer on delegate property is automatically called for superclasses, therefore no need to call super.<blah> explicitly, and no risk to 'forget' doing so
  • Concrete delegate properties can be kept private on each level of inheritance, thereby reducing the clutter.
like image 81
0x416e746f6e Avatar answered Oct 04 '22 12:10

0x416e746f6e