preface

In a previous article briefly mentioned this problem, but their own writing is not detailed, and their in-depth understanding is not particularly much, in the development of how to use, so after the reader’s feedback on this problem is very confused! This article will analyze the previous deficiencies, if there is something wrong, please help to correct it!

Related Article: Do you Encounter these Experience problems in iOS Development (Part 2)

1. Use level understanding

Here we first talk about how to use the simple, just use the level (there are misunderstandings to help correct), and then we go to understand the bit operators! In the figure below we can see that the enumeration value has <<(bitwise operator: left shift):

If we see < < in the enumeration values that we can through | (operator: or) are combined using the following code:

 // Add a random UITextField
 UITextField *field = [UITextField new];
 //Begin,Changed,DidEnd all trigger UITextField events
 [field addTarget:self action:@selector(textFieldDidChanged) forControlEvents: UIControlEventEditingDidBegin |
                  UIControlEventValueChanged |
                  UIControlEventEditingDidEnd
     ];

 [self.view addSubview:field];Copy the code

Enumerations without << are normal NSInteger enumerations, so they cannot be combined:

So how did Apple officials know we were using multiple conditions in combination? The answer is determined by the &(bit operator: and) :

ControlEvents is a combined value
 NSUInteger controlEvents = UIControlEventEditingDidBegin | UIControlEventValueChanged | UIControlEventEditingDidEnd;
    /**
    //通过 & 来判断是否包含:
    UIControlEventEditingDidBegin,
    UIControlEventValueChanged,
    UIControlEventEditingDidEnd
     */
    if (controlEvents & UIControlEventEditingDidBegin) {

        NSLog(@"UIControlEventEditingDidBegin");

    }else if (controlEvents & UIControlEventValueChanged) {

        NSLog(@"UIControlEventValueChanged");

    }else if (controlEvents & UIControlEventEditingDidEnd) {

        NSLog(@"UIControlEventEditingDidEnd");
    }Copy the code

So let’s take a look at the bit operators involved in using them. We’ll give an example below!

2. Understand bitwise operators

First we have an enumeration, and we’ll leave the following two ways of writing it out for the moment. After the allelic operators, we’ll talk about macro use of enumeration:

//typedef NS_OPTIONS(NSInteger, myTests) {
// nameA = 1 << 0,
// nameB = 1 << 1,
// nameC = 1 << 2,
// nameD = 1 << 3,
/ /};

typedef enum {
    nameA = 1 << 0,
    nameB = 1 << 1,
    nameC = 1 << 2,
    nameD = 1 << 3,

}myTests;

NameC = 1 << 2: nameC = 1 << 2: nameC = 4(2 ^ 2) nameC = 1 << 3: nameC = 8(2 ^ 3) */Copy the code

To judge by &, let’s see the output result as shown in the figure below:

We get NSInteger value = nameA | nameB; NameC = “nameC”; nameC = “nameC”; nameC = “nameC”; nameC = “nameC”;

The other thing is value & nameA is the value of nameA is 1, value & nameB is the value of nameB is 2

  • <<(left) :a << bHe saidaMove left after converting to binarybBit (add afterba0)
  • |(or): As long as there is a1The result is that1
  • &(and): As long as there are two1The result is that1

NameA = 1, nameB = 2, nameC = 4, nameD = 8

 NSIntegervalue = nameA | nameB | nameC | nameD; Convert to binary: nameA:0 0 0 1
       |
     nameB: 0 0 1 0
       |
     nameC: 0 1 0 0
       |
     nameD: 1 0 0 0
    ----------------
     value: 1 1 1 1The above is to use | it is concluded that the value has a value of1111(| mean one1The results for1The following is the use of ampersand to determine the value of the output (ampersand means that there are two1The results for1)

      value: 1 1 1 1         value: 1 1 1 1
        &                      &
      nameA: 0 0 0 1         nameB: 0 0 1 0---------------- ---------------- Result value:0 0 0 1The resulting value:0 0 1 0I will write2Example:0001That's the value of nameA,0010That's the value of nameBCopy the code

Now that you know what’s going on, let’s take a look at enumeration macros. For better reading, we can also look at the following screenshots:

3. Enumeration macros (NS_ENUMwithNS_OPTIONS)

The NS_ENUM and NS_OPTIONS macros provide a concise, easy way to define enumerations and C language options.

The NS_ENUM and NS_OPTIONS macros provide a concise, simple way of defining enumerations and options in C-based languages. These macros improve code completion in Xcode and explicitly specify the type and size of your enumerations and options. Additionally, this syntax declares enums in a way that is evaluated correctly by older compilers, and by newer ones that can interpret the underlying type information.

This is how it was initially used:

enum {
        UITableViewCellStyleDefault.UITableViewCellStyleValue1.UITableViewCellStyleValue2.UITableViewCellStyleSubtitle
};
typedef NSInteger UITableViewCellStyle;

--------------------------------------------------

enum {
        UIViewAutoresizingNone                 = 0.UIViewAutoresizingFlexibleLeftMargin   = 1 << 0.UIViewAutoresizingFlexibleWidth        = 1 << 1.UIViewAutoresizingFlexibleRightMargin  = 1 << 2.UIViewAutoresizingFlexibleTopMargin    = 1 << 3.UIViewAutoresizingFlexibleHeight       = 1 << 4.UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
typedef NSUInteger UIViewAutoresizing;Copy the code

By using enumeration macros:

NS_ENUM: An enumeration used to declare a generic NSInteger(NSInteger is used in the code below) type

Use the NS_ENUM macro to define enumerations, a set of values that are mutually exclusive.

NS_OPTIONS: is used to declare bitmasks.

Use the NS_OPTIONS macro to define options, a set of bitmasked values that may be combined together.

//NS_ENUM
typedef NS_ENUM(NSInteger.UITableViewCellStyle) {
        UITableViewCellStyleDefault.UITableViewCellStyleValue1.UITableViewCellStyleValue2.UITableViewCellStyleSubtitle
};

--------------------------------------------------

//NS_OPTIONS
typedef NS_OPTIONS(NSUInteger.UIViewAutoresizing) {
        UIViewAutoresizingNone                 = 0.UIViewAutoresizingFlexibleLeftMargin   = 1 << 0.UIViewAutoresizingFlexibleWidth        = 1 << 1.UIViewAutoresizingFlexibleRightMargin  = 1 << 2.UIViewAutoresizingFlexibleTopMargin    = 1 << 3.UIViewAutoresizingFlexibleHeight       = 1 << 4.UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};Copy the code

How does NS_OPTIONS differ from NS_ENUM and enum?

1. From the above introduction, we can see that enum can declare the general type and bitmasked type

2.NS_ENUM declares the common type, and NS_OPTIONS declares the bitmasked type

3. Why not use enum instead? The answer is no. Apple recommends that we use NS_ENUM and NS_OPTIONS in OC. Why? In addition to infering different types of enumerations, they produce different code when compiling objective-C ++ schemas, so using enums when mixing results in an error! Check out the answer to stackOverflow! I do not know whether there is a mistake in my understanding, if there is a mistake, I hope to help correct it!