title: Understand the programming mechanism of Protocol and Delegate date: 2022-05-05 09:34 summary: Whether it is the earlier Objective-C or the current Swift, as long as we write an App on iOS (including macOS), we will see a lot of Delegaterelated instructions in the official documents, as well as what is the Protocol behind it. ? Understanding the basic concepts will be helpful for getting started. Review compiled and scripted types Compiled (static) and scripted (dynamic), as two different types of programming languages, we have made some brief introductions in [["Understanding Two Technical Languages by Cooking Hotpot"]]. Swift is a compiled programming language. First of all, type declaration is necessary. What is a type declaration? In short, a variable is an integer, with a decimal point, text type, etc. From the beginning to the end, we all know what type it is. Not only that, what type of variable input does a function process, and how is it processed? The variable output is also determined. For a dynamic language like Python, this type is undefined. But the two are not absolutely good or bad, and they also have similar intersections. For example, there are arbitrary types of data such as Any and AnyObject in Swift. Of course, the final conversion will also follow the internal inherent type convention. In Python 3, variable types are already allowed to be declared in the process of writing code (does not affect the actual run logic). The advantage of strong type convention is that it can keep the code structure of the overall project stable, while the advantage of weak type is that it is more flexible. Protocol and Delegate for iOS Whether it is the earlier Objective-C or the current Swift, as long as we write apps on iOS (including macOS), we will see a lot of Delegate-related instructions in the official documents. As an object that controls App organization, both NSApplication (macOS) and UIApplication (iOS) have their own delegate assignments. On iOS, a webview (WKWebView) can obtain external control of scrolling, called webview.scrollView, and it also has delegates. To handle some scrolling logic, there are also delegates on webview, such as webview.navigationDelegat and webview.uiDelegate. **What exactly is a Delegate? **If you especially look at the official development documents, you will even feel that half of the document is based on Delegate. Delegate is translated into Chinese, which is probably delegation, delegation. In short, when a certain delegate (object) is set, some inherent logic will be delegated to the corresponding delegate (object) Dealt with it. Behind these "inherent logic" is usually Protocol. Protocol is much easier to understand. It is a protocol, or a contract, or it can be considered a framework with a fixed format. At this time, some friends want to ask, why not inherit the logic of the parent class and subclass? This is certainly possible, but it is not flexible enough. Generally speaking, delegate and protocol are optional, especially for some components provided by Swift/OC itself. Even if a delegate is not specified, it will not affect the operation of the component. On the other hand, even if we apply the logic of delegate & protocol in the coding process and make it required to assign values, then the advantage it has over parent classes and subclasses is that we don’t need to write a lot overwrite (cover, rewrite) this additional statement. **A more critical point is that in Xcode, once a delegate is assigned, the corresponding protocol methods behind the delegate will be filled in once, and then you can just complete these methods directly, which is equivalent to an active built-in document. ** Example description A Protocol looks like this. We have declared several methods (method, function) functions. UniversalView is not an inherent variable type on iOS or macOS, but an automatic matching. On iOS, it corresponds to UIView, on macOS It corresponds to NSView, and StringAnyDict is a custom-defined data type. By the way, why is it a Python-style variable name like "cell_get_count" instead of an Apple-style variable name like "cellGetCount"? I'm used to it myself, and I don't have to be responsible for others in the team... public protocol CommonTableViewControllerDelegate: AnyObject { func cell_get_count() -> Int func cell_get_data(_ item_index: Int) -> StringAnyDict func cell_create_view() -> UniversalView func cell_setup_view(view: UniversalView, data: StringAnyDict) } Then, within a Class that requires this protocol, make a declaration: public weak var delegate: CommonTableViewControllerDelegate?=nil Then, in this Class, certain specific links call the delegate, such as: public func get_items_count() -> Int { if self.delegate != nil { return self.delegate!.cell_get_count() } return 0 } Of course, the get_items_count function can be overridden and rewritten in subclasses, but with the logic of delegate, there is no need to do this. The last step is practical application. For example, the name of the Class just now is CommonTableViewController. Next, we need to inherit it in a new class and assign a delegate. In addition to specifying the parent class, we also add the Protocol to be followed. The approximate code logic is as follows: class KeyboardShortcutsSortController: CommonTableViewController, CommonTableViewControllerDelegate { init(){ //Initialization self.delegate = self } } Then, Xcode will automatically help you fill in the corresponding functions in the following Protocols. Just write the specific content yourself. func cell_get_count() -> Int { } func cell_get_data(_ item_index: Int) -> StringAnyDict { } func cell_create_view() -> UniversalView { } What are the benefits? Protocol and Delegate are like a strong contract. In the process of writing code, we actually follow many "conventions" ourselves, most of which are weak conventions. Strong conventions are helpful for projects. From the perspective of "writing code", it will actually improve the user experience of writing code itself. In addition, they are also like a kind of interface exposure rules that can maintain some underlying uniformity. For example, in the "Example Description" above, the code here is an actual code snippet from an iOS project of mine, but this part of the Delegate and Protocol spans iOS and macOS. In other words, as long as I implement it on macOS If the same (basic) method is adopted, the same set of code can be used in the presentation layer above the delegate regardless of iOS or macOS. It can substantially reduce the workload of the code, and it is actually easier to maintain. By the way, at this point, I have to mention, why not use something like SwiftUI to achieve crossplatform between iOS and macOS (within the Apple ecosystem)? Imagination is always beautiful. In some relatively complex scenarios, in order to achieve [[First appearance]] or a reliable user experience, generally speaking, there is no quick way to achieve it. You can't be lazy, you have to pay the price for being lazy. cards Swift has arbitrary types of data such as Any and AnyObject, and in Python 3, variable types are already allowed to be declared during the process of writing code. The advantage of strong type convention is that it can keep the code structure of the overall project stable, while the advantage of weak type is that it is more flexible, but they all tend to reach the same goal through different paths. Why is it a Python-style variable name like “cell_get_count” instead of an Apple-style variable name like “cellGetCount”? I'm used to it myself, and I don't have to be responsible for others in the team... Why not use something like SwiftUI to achieve cross-platform between iOS and macOS (within the Apple ecosystem)? Imagination is always beautiful. In some relatively complex scenarios, in order to achieve "first appearance" or a reliable user experience, generally speaking, there is no easy way. You can't be lazy, you have to pay the price for being lazy.