Someone asked me a great question, which I summarized as: "Should we choose blocks or delegates during development? When we need to implement callbacks, which method is more appropriate?" Usually in this situation, I like to ask myself: "If the problem was handed to Apple, what would it do?" Of course, we all know that Apple must know how to do it, because at a certain level, Apple's documentation is a guide book to teach us how to use design patterns. Therefore, we need to study the situations in which Apple uses delegates and blocks. If we find the routines of Apple making such choices, we can build some rules to help us make the same choices in our own code. It is easy to find out the scenarios where Apple uses delegates. We just need to search for "delegate" in the official documentation and we will get many classes that use delegation. But it is a bit difficult to search for Apple's documentation on using blocks, because we can't directly search for "^" in the documentation. However, Apple has a good naming habit when declaring methods (which is also a necessary skill for us to master iOS development). For example: a method that takes NSString as a parameter will have the word String in the method's selector, like initWithString; dateFromString; StartSpeaingString. When an Apple method uses blocks, the method will have "Handler", "Completion", or simply "Block" as a selector; so we can search for these keywords in the standard iOS API documentation to build a list of reliable block use cases. 1. Most delegate protocols have several message sources. Take GKMatch, which I'm looking at, for example (A GKMatch object provides a peer-to-peer network between a group of devices that are connected to Game Center, which is an object in the iOS API used to provide a group of devices connected to the Game Center peer-to-peer network). From this class, you can see that the sources of messages are: when data is received from other players, when a player switches state, when an error occurs, or when a player should be re-invited. These are all different events. If Apple uses blocks here, there may be two solutions: You can register a corresponding block for each event, but this approach is obviously unreasonable. (If someone writes a class that does this in Objective-C, they are probably an asshole.) Create a block that can accept any possible input 1 Obviously this is neither easy nor readable, so you probably never see this solution. If you do see this solution, it's obviously a terrible line of code that you won't bother maintaining. Therefore, we can draw a conclusion: if the object has more than one different event source, use delegation. 2. An object can only have one delegate Since an object can only have one delegate, and it can only communicate with this delegate, let's look at the CLLocationManager class. When a location is discovered, the location manager will only notify one object (one and only one). Of course, if we need more objects to know about this update, we can create other location managers. Some people here may think, what if CLLocationManager is a singleton? If we can't create other instances of CLLocationManager, we must constantly switch the delegate pointer to the object that needs geographic data (or create a sophisticated broadcast system that only you understand). Therefore, it seems that delegation doesn't make much sense on a singleton. The best example of this is UIAccelerometer. In early versions of iOS, the singleton accelerometer instance had a delegate, which forced us to switch it occasionally. This stupid problem was fixed in later iOS versions, and now any object can access the CMMotionManager block without blocking other objects to receive updates. Therefore, we can draw another conclusion: "If an object is a singleton, don't use delegation." 3.General delegate methods will have return values If you observe that some delegate methods (almost all dataSource methods) have a return value. This means that the delegating object is asking for the state of something (the value of an object, or the object itself), and a block can legitimately contain state or at least infer state, so the block is really a property of the object. Let's think about an interesting scenario, if we ask a block: "What do you think about Bob?". The block may do two things: send a message to a captured object and ask the object what it thinks of Bob, or return a captured value directly. If it returns an object response, we should bypass the block and get the object directly. If it returns a captured value, then this should be a property of the object. From the above observations, we can conclude that if the object request carries additional information, delegation should be used. 4. Process vs. Results If we look at NSURLConnectionDelegate and NSURLConnectionDataDelegate, we can see messages in the protocol like: what I am going to do (e.g. willSendRequest, will send the request), what I know so far (e.g. canAuthenticateAgainstProtectionSpace), I have done this (didReceiveResponse, received the response to the request, that is, completed the request). These messages form a process, and the delegates who are interested in the process will be notified at each step. When we look at the handler and the complete method, we see a block containing a response object and an error object. Clearly there is no "where am I, what am I doing" interaction here. Therefore, we can think that the delegate callback is more process-oriented, while the block is result-oriented. If you need to be notified of a multi-step process, you should use delegation. If you just want to get the information you requested (or an error message when getting the information), you should use a block. (If you combine the previous 3 conclusions, you will find that the delegate can maintain state in all events, while multiple independent blocks cannot) From the above we can draw two key points. First, if you use a block to request a request that may fail, you should only use one block. We can see the following code: The readability of the above code is obviously worse than that of the following block (the author said this is his immodest opinion, but I personally think it is not that serious) |
<<: To game CPs: Think twice before choosing a publisher
>>: Jack Ma: "I had a sleepless night in Seattle last night"
The launch of mini programs has brought convenien...
In the framework of traditional Chinese culture, ...
After a month, Gree Group's 5.2 billion acqui...
Written by Wei Shuihua Header Image | Who is the ...
Do you like eating crabs? It is the season of cra...
According to media reports, Zhang Hengyuan, the r...
Produced by: Science Popularization China Author:...
[Hot Mom Guide] How to quickly recover your girli...
*The pictures of Dunhuang murals in this article ...
Recently, a news report about a man who ate three...
On October 2, at 11:45 CET (17:45 BJT), the Nobel...
The so-called traffic diversion means that there ...
This is one in a series of articles exploring Lin...
When Nexus 4 was first launched, it was sold out f...
On May 31, Xiaomi released its new flagship smart...