This is the 11th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021 “.

Protocols are a very powerful feature of Swift. Together with generics and functions, they are the three cornerstones of SWIFT.

agreement

A protocol is an interface that describes properties and methods used to specify specific type or instance properties. Attribute requirements are declared as attribute variables by the “var” keyword.

protocol NameProtocol {
   var name: String { get set }
   var successed: Bool { get }
   func getName() -> String
}
Copy the code

Protocol initialization

Swiftng allows users to initialize protocols in a manner similar to normal type initialization. If the class inherits the protocol, it must implement the protocol initialization method and must write the required keyword.

protocol NameProtocol {
   init(name: String)
}

class Person: NameProtocol {
   required init(name: String) {
   }
}

Copy the code

Protocol conformance ensures explicit or inherited implementation through the “required” modifier on all subclasses. When a subclass overrides its superclass initialization requirements, it is specified by the “override” keyword.

protocol NameProtocol {
   init(name: String)
}

class MainClass {
   var name: String       
   init(name: String) {
      self.name = name  
   }
}

class SubClass: mainClass, NameProtocol {
   var context: String
   init(name: String, context : String) {
      self.context = context
      super.init(name:name)
   }

   required override convenience init(name: String) {
      self.init(name:name, context:"")
   }
}
Copy the code

Protocol combinations

Swift’s Hashable protocol inherits from Equatable, and Comparable inherits from Equatable, so it’s kind of like we’re writing protocols for the same function points. Swift also allows us to combine two protocols using type identifiers, which makes the protocols easy to combine and functional. SwiftCodable is already doing just that.

typealias Codable = Decodable & Encodable
Copy the code

Protocol extensions

It is also acceptable to write protocol method declarations without implementing them, but it is useful and common in practice to provide default implementations for these protocol methods. Make them “optional” by providing default implementations of protocol methods and default values for protocol properties. Such protocol-compliant types can be reimplemented on their own or use the default implementation. And if the implementation logic for multiple types is the same, it is possible to refine using the default implementation without having to repeat the implementation for each type individually. The ability to extend existing protocols with default behavior is very powerful, allowing protocols to grow and extend without fear of breaking the compatibility of existing code.

protocol NameProtocol {
   func getName() -> String
}

extension NameProtocol {
    func getName() {
        return "name"
    }
}
Copy the code

Swift also allows us to add such conditions to the protocol extension using the WHERE keyword. This can be done only for certain situations.

extension NameProtocol where Self: UIViewController {
    func getName() {
        return "UIViewController"
    }
}
Copy the code

Self (capital “S”) in the above snippet refers to a type (structure, class, or enumeration). You can extend the protocol only for types inherited from UIViewController by specifying a class.

Class only protocol

Sometimes it’s useful to be able to restrict your protocol to a class so that only the class can conform to it. When you want to call protocol methods: Classes are free to change their variable properties, structures are not. The correct way to declare a class-only protocol in Swift code is to use AnyObject:

protocol MyProtocol: AnyObject { }
Copy the code

But when you look at someone else’s old code you find this class-only protocol (this is the old implementation) :

protocol MyProtocol: class { }
Copy the code

Agreement conflict

protocol P1 {
    var name: String { get set }
    func method()
    //some other methods
}

protocol P2 {
    var name: String { get set }
    func method()
    //some other methods
}

extension P1 {
    func method() {
        print("Method P1")
    }
}

extension P2 {
    func method() {
        print("Method P2")
    }
}

Copy the code

When there is a type, it conforms to both protocols. In this case, we run into problems with the implementation of undefined methods or properties. This type does not make it clear which protocol methods should be used to implement it. Here are two ideas:

  • 1. Implement undefined methods or properties in inheritance.
struct Name: P1, P2 {
    var name: String
    func method() {
        print("Method S")
    }
}
Copy the code
  • 2: Operates the protocol as a type.
struct Name {
    var p1: P1
    var p2: P2
    func method() {
       _ = p1.name
       _ = p2.name
        p1.method()
        p2.method()
    }
}

Copy the code