Arbitrary combination judgments are still understood with the Switch? Bit operator~


Scenario Reproduction

Many times, when we write programs, there will be such a situation, that is, code multiple-choice operations. For example, the following operations.

For example, there are four view views (A, B, C, D, respectively).
When the button a is clicked, the background color of view A and B changes.
When the button b is clicked, the background color of view A, b and D changes.
When the button c is clicked, the background color of view B, c and D changes.
There may be many buttons and different combinations in subsequent development.

What will you do then?

  • The first is that all buttons respond to a method that uses modules such as if el se to distinguish different button events.
    Think about it: Later, if you add a button, you need to add an if else. As the code increases, too many logical levels of if else are not good for reading.

  • Second solution: if else performance is too low? We use Switch. With the enumeration value or the Tag value of the button to make a distinction, the enumeration value can be defined as each combination form is an enumeration value. Different buttons have the same combination form and enter the same module.
    Think about it: Although Switch uses break keywords to improve performance significantly compared with ordinary if else, if you add a case later, you still need to add code blocks. Or it will increase the amount of code.

At this time, let's sum up what needs to be done and what problems have arisen.

  • Requirements: The portfolio is uncertain, but the basic elements of the portfolio are deterministic (any combination in A,B,C,D).
  • Question: Ordinary ways, no matter if else or Switch, may need to list all the combinations. The amount of code is very large and does not conform to the code specification. It is also quite difficult to read.

Isn't there a more elegant way to solve this problem? Of course there is, that's our pig-foot operator today. The use of bit operators can help us solve this problem very well. But before that, we need to know what is called displacement operator.


Bitwise Operators

Symbol Name Effect
<< Left shift If the whole binary of an integer is left shifted to n bits, such as the bit operation 5 << 1 of integer 5 (binary representation 0101), then the result is integer 10 (binary representation 1010).
>> Right shift Move the whole binary of an integer right by n bits, similar to the left-shift operator.
>>> unsigned right shift Move all the digits to the right in binary form, move them out (discard) at low displacement, and fill in the empty space at high position. For positive numbers, it's the same as right shift with sign, but different for negative numbers.
& Location and If the corresponding two binary bits are both 1, the result bits will be 1. Otherwise, the result bits will be 0, for example, 5-9=1, which is interpreted as 0101-1001=0001, and will be converted to an integer of 1.
| In place or As long as one of the corresponding binary bits is 1, the result bit is 1, otherwise it is 0.
^ XOR As long as the corresponding two binary bits are different, the result bit is 1, otherwise it is 0.
~ Inverse code Binary inversion of the number participating in the operation turns 1 to 0 and 0 to 1.

Let's look at bitwise and bitwise or give an example.

Location and
 1001
 &
 0101
=0001
In place or
 1001
 &
 0101
=1101
xor
 1001
 ^
 0101
=1100

We know about bit operators. How do we solve the initial problem? Let's go on and see.~


Solve the problem

Demo Portal

To solve this problem, we will use the three bit operators of sum and & and |.

First, define a ColorView view, inherit from UIView, and then define enumerations in the. h header file, and ColorView holds the properties of enumerations. The code is shown below.

#import <UIKit/UIKit.h>

typedef enum : NSUInteger {
    ColorViewStyleA     = 1<<0,
    ColorViewStyleB     = 1<<1,
    ColorViewStyleC     = 1<<2,
    ColorViewStyleD     = 1<<3,
} ColorViewStyle;

@interface ColorView : UIView

@property(nonatomic,assign)ColorViewStyle style;
@property(nonatomic,copy)NSString *title;

@end

Then import ColorView into ViewController and declare an attribute needChangeColorStyle. Used to determine the view that needs to be modified.

#import "ColorView.h"
@interface ViewController ()

@property(nonatomic,assign)ColorViewStyle needChangeColorStyle;

@end

Then I created ColorView and Button in ViewController, which I sketched for time reasons. The main thing is to set an enumeration value for each view as an identifier.

    //Create ColorView
    for (int i = 0; i < 4; i++) {
        
        ColorView *colorView = [[ColorView alloc] initWithFrame:CGRectMake(viewWidth * i + distance *(i+1), 100, viewWidth, 100)];

        ............

        switch (i) {
            case 0:
                colorView.style = ColorViewStyleA;
                break;
            case 1:
                colorView.style = ColorViewStyleB;
                break;
            case 2:
                colorView.style = ColorViewStyleC;
                break;
            case 3:
                colorView.style = ColorViewStyleD;
                break;
        }
       ............
    }

    //Create buttons
    for (int i = 0; i < 4; i++) {
       ............
    }

Then reset the value of needChangeColorStyle in the button action click method of the button, where you need to use bitwise or combinations of enumerated values. As shown below.

- (void)buttonAction:(UIButton *)sender {
    
    //Assignment of needChangeColorStyle, in fact, this step should be done at the beginning, here is Demo, so do it.
    //Bit-by-bit or operator is used in the assignment process. Responsible View types are integrated.
    NSInteger tagIndex = sender.tag - 10000;
    switch (tagIndex) {
        case 0:
            _needChangeColorStyle = ColorViewStyleA|ColorViewStyleB|ColorViewStyleD;
            break;
        case 1:
            _needChangeColorStyle = ColorViewStyleB|ColorViewStyleC|ColorViewStyleD;
            break;
        case 2:
            _needChangeColorStyle = ColorViewStyleA|ColorViewStyleB;
            break;
        case 3:
            _needChangeColorStyle = ColorViewStyleD;
            break;
    }
    [self colorViewsChangAction];
}

Finally, the operation selection of the view is made in the colorViews ChangAction method. Bit-by-bit and operation are used. As long as the style and _needChangeColorStyle of the view have intersecting parts, the value of the two bits and Style must be greater than or equal to 1. Thus, the inclusion operation can be done. As shown below in the code day.

- (void)colorViewsChangAction {
    
    //Traversing through the ColorView view array
    for (ColorView *colorView in self.colorViews) {
        //Bit-by-bit and-by-bit are used to see if they have an intersection.
        if (_needChangeColorStyle & colorView.style) {
            NSLog(@"%@ Responding",colorView.title);
            colorView.backgroundColor = [UIColor redColor];
        } else {
            colorView.backgroundColor = [UIColor orangeColor];
        }
    }
}

In the end, we add a button or a combination form. We only need to add three lines of code to the buttonAction. The rest is not needed, and the code structure is very comfortable to read.

Of course, there are also such operations in the iOS native framework, such as trimming the specified angle of the Bessel curve. The enumeration value is also with displacement operation. The enumeration value is shown below. At this time, you can still use any form of angle in bits or combinations.

typedef NS_OPTIONS(NSUInteger, UIRectCorner) {
    UIRectCornerTopLeft     = 1 << 0,
    UIRectCornerTopRight    = 1 << 1,
    UIRectCornerBottomLeft  = 1 << 2,
    UIRectCornerBottomRight = 1 << 3,
    UIRectCornerAllCorners  = ~0UL
};


summary

Bit operators have many other uses, which is the simplest one. If there are performance problems in enumeration on Android side, you can use the form of defining constants to achieve this purpose. It's consistent as a whole. Well, here we go. If there are any problems, you are welcome to criticize and guide. Thank you. Finally, send Demo again.

Demo Portal


Keywords: Attribute REST iOS Android

Added by jokerofsouls on Mon, 17 Jun 2019 21:28:32 +0300