ios--development This choice blocks or delegates

Source: Internet
Author: User

Original link: http://blog.stablekernel.com/blocks-or-delegates/

Someone asked me a great question, and I summed up the question as: "is the choice blocks or delegates during development?" When we need to implement callbacks, which is the appropriate way to use it? ”

Generally in this case, I like to ask myself: "What would he do if the problem was given to Apple?" "Of course, we all know that Apple certainly knows how to do this, because at a certain level, Apple's documentation is a guide to how we use design patterns."

So we need to look at the circumstances under which Apple uses delegate and block, and if we find out how Apple makes this choice, we can build rules that help us make the same choices in our own code.

To find out where Apple is using delegate is simple, we just search for "delegate" in the official documentation, and we get a lot of classes that use delegation.

But searching for documents in Apple about using blocks is a bit difficult because we can't directly search for "^" in the document. However, Apple has a good naming habit when it comes to declaring methods (which is one of the skills we have to be proficient in iOS development). For example: A method that takes nsstring as the parameter, the selector of the method will have string word, like initwithstring;datefromstring; Startspeaingstring.

When Apple's method uses block, this method will have "Handler", "completion" or simple "block" as selector, so we can search the standard iOS API documentation for these keywords, Used to build a list of trusted block use cases.

1. Most delegate protocols have several sources.

Take the Gkmatch I'm looking at, for example (a Gkmatch object provides a peer-to-peer network between a group of devices that is connected to Game Cen ter, which is the object used in the iOS API to provide a set of devices connected to the game center point-to-point network. From this class, you can see the source of the message: When the data is received from other players, when the player switches the state, when an error occurs, or when a player should be re-invited. These are different events. If Apple uses block here, there are two possible ways to resolve this:

    • The corresponding block can be registered for each event, which is obviously unreasonable. (If someone writes a class that does this in objective-c, they is probably an asshole.)

    • Create a block that can accept any possible input

1 void?(^matchBlock)(GKMatchEvent?eventType,?Player?*player,?NSData?*data,?NSError?*err);

It is obvious that this is not easy and difficult to read, so you may never have seen this solution. If you've seen this solution, but it's obviously a bad line of code, you won't have the energy to maintain it.

Therefore, we can draw a conclusion: if the object has more than one different event source, use delegation.

2. An object can have only one delegate

Because an object can have only one delegate, and it can only communicate with this delegate. Let's take a look at the Cllocationmanager class, when the location manager notifies only one object (with only one) when the geolocation is discovered. Of course, if we need more objects to know about this update, we'd better create another location manager.

Some people here may think, if Cllocationmanager is a singleton? If we cannot create other instances of Cllocationmanager, we must constantly switch delegate pointers to objects that require geographic data (or create a sophisticated broadcast system that only you understand). Thus, it seems that delegatetion does not make much sense in a single case.

The best example of this is uiaccelerometer. In earlier versions of iOS, the singleton accelerometer instance had a delegate, which led us to have to switch occasionally. This stupid question. After the iOS version has been modified, any object can now access the Cmmotionmanager block without having to block other objects from receiving updates.

Therefore, we can draw another conclusion: "If an object is a singleton, do not use delegation."

3. The general delegate method will have a return value

If you look at some delegate methods (almost all DataSource methods) There is a return value. This means that the delegating object is requesting something in the state (the value of the object, or the object itself), while a block can reasonably 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 you ask a block: "What does think about Bob?" ”。 Block may do two things: send a message to capture the object and ask the object how to look at Bob, or return a captured value directly. If the response of an object is returned, we should get this object directly over the block. If it returns a captured value, then this should be the property of an object.

From the above observation, we can conclude that if the object request has additional information, the delegation should be used.

4. Process vs. Results (processes vs. Results)

If you look at Nsurlconnectiondelegate and nsurlconnectiondatadelegate, we can see a message like this in the protocol: What I'm going to do (such as: Willsendrequest, will send the request), so far I know the information (such as: Canauthenticateagainstprotectionspace), I have completed these (Didreceiveresponse, received the requested reply, that is, the completion of the request). These messages form a process, and the delegate that are interested in the process are notified at each step.

When we look at handler and the complete method, we find that a block contains a response object and an Error object. Obviously there is no interaction here about "where I am, what I am doing".

So we can say that delegate's callbacks are more process-oriented, and blocks are results-oriented. If you need to get notifications for a multi-step process, you should use delegation. And when you just want to get the information you requested (or get the message wrong), you should use block. (If you combine the previous 3 conclusions, you will find that delegate can maintain state in all events, while multiple independent blocks do not)

We can draw two key points from the above. First, if you use block to request a potentially failed request, you should use only one block. We can see the following code:

12345 [fetcher makeRequest:^(id result) {   // do something with result} error:^(NSError *err) {    // Do something with error}];

The readability of the above code is significantly lower than that of the block below (the author says this is his humble opinion, in fact, personally think it is not so serious)

1234567 [fetcher makeRequest:^(id result, NSError *err) {     if(!err) {         // handle result     else{        // handle error     }}];

 

ios--development This choice blocks or delegates

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.