Whether to select Blocks or Delegates during development

Source: Internet
Author: User

Whether to select Blocks or Delegates during development

In this case, I like to ask myself: "If the question is left to Apple, what will he do ?" Of course, we all know that Apple must know how to do this, because at a certain level, Apple's documentation is a guide to guide us through design patterns.

Therefore, we need to study the situations in which Apple uses delegate and block. If we find that Apple makes this choice, we can build some rules, this helps us make the same choice in our own code.

To find out how Apple uses delegate, we only need to search for "delegate" in the official documentation and obtain many delegation classes.

However, it is a little difficult to search for blocks documents in Apple, because we cannot directly search for "^" in the documents ". However, Apple has a good Naming Convention (this is also a required skill for us to be proficient in iOS development ). For example, for a method that uses NSString as the parameter, the selector of the method has the String word, such as initWithString; dateFromString; StartSpeaingString.

When Apple's method uses block, this method will have "Handler", "Completion", or a simple "Block" as the selector; therefore, we can search for these keywords in the standard iOS API document to build a list of trusted block use cases.

1. Most delegate protocols have several sources.

Take the GKMatch I am reading as an example (A GKMatch object provides a peer-to-peer network between a group of devices that are connected to Game Center, is an object in the iOS API that provides a group of devices to connect to the Game Center point-to-point network ). In this category, we can see that the sources of messages are: when data is received from other players, when the player switches to the status, when an error occurs, or when a player should be invited again. These are all different events. If Apple uses block here, there may be two solutions:

The corresponding block can be registered for each event. Obviously, this method is unreasonable. (If someone writes a class that does this in Objective-C, they are probably an asshole .)

Create a block that can accept any input

1

Void (^ matchBlock) (GKMatchEvent eventType, Player * player, NSData * data, NSError * err );

Obviously, this method is neither simple nor easy to read, so you may have never seen such a solution. If you have seen such a solution, but this is obviously an extremely bad line of code, you will not have the energy to maintain this.

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

Because an object can only have one delegate, and it can only communicate with this delegate. Let's take a look at the CLLocationManager class. When a geographical location is found, location manager will only notify one object (one and only one ). Of course, if we need more objects to know the update, we 'd better create other location managers.

Some people may think that what if CLLocationManager is a Singleton? If we cannot create other CLLocationManager instances, we must constantly switch the delegate pointer to the objects that require geographic data (or create a precise broadcast system that only you understand ). Therefore, it seems that delegatetion does not make much sense in a singleton.

The best example is UIAccelerometer. In earlier versions of iOS, the single-instance accelerometer instance has a delegate, so we have to switch between them occasionally. This silly problem was modified in later IOS versions. Now, any object can access the CMMotionManager block without blocking other objects from receiving updates.

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

3. The delegate method returns a value.

If you observe that some delegate methods (almost all dataSource methods) have a return value. This means that the delegating object is requesting the state of something (the object value, or the object itself), and a block can reasonably contain the state or at least infer the state, therefore, block is really an attribute of an object.

Let's think about an interesting scenario. If you ask a block: "What do you think about Bob ?". Block may do two things: Send a message to capture the object and ask how the object views Bob, or directly return a captured value. If the response of an object is returned, we should retrieve the object directly from this block. If it returns a captured value, this should be an object attribute.

From the above observations, we can conclude that if the object's request carries additional information, we should use delegation.

4. Process vs result (Process vs. Results)

If you want to view NSURLConnectionDelegate and NSURLConnectionDataDelegate, we can see the following message in protocol: what will I do (for example, willSendRequest, will send a request), information I know so far (for example: canAuthenticateAgainstProtectionSpace), I have already completed these tasks (didReceiveResponse, And the request is completed after receiving a reply from the request ). These messages form a process, and the delegate that is interested in the process will be notified at each step.

When we observe handler and the complete method, we find that a block contains a response object and an error object. Obviously, there is no interaction on "where I am, what I am doing.

Therefore, we can think that the delegate callback is more process-oriented, while the block is result-oriented. If you need to get a multi-step process notification, you should use delegation. When you only want to get the information you requested (or an error message when getting the information), you should use block. (If you combine the previous three conclusions, you will find that delegate can maintain state in all events, but multiple independent blocks cannot)

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

[Fetcher makeRequest: ^ (id result ){

// Do something with result

} Error: ^ (NSError * err ){

// Do something with error

}];

The readability of the above Code is obviously worse than that of the following block (the author said that this is his humble opinion, in fact, I personally think it is not that serious)

[Fetcher makeRequest: ^ (id result, NSError * err ){

If (! Err ){

// Handle result

} Else {

// Handle error

}

}];

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.