In this article, we start with simple declarations in C, move on to complex declaration combinations, and finally the syntax of code blocks in Objective-C. Spend some time to understand the derivation and organization of code blocks. Once you understand these, you can easily declare and use them without having to Google them every time you need them. If you want to express anything you can think of using block declarations, keep reading! Declarators In C language, variables are declared using descriptors. A specifier has two effects:
Let's start with a very basic specifier: ? This is a lot like the first line of C code you ever wrote. int is the basic variable type, and a is the name (or identifier) of the variable. When you start looking at a specifier, you should start with the variable name (the specifier), read the part to the right of the variable name, and then read the part to the left of the variable name (the following section explains why this is done). In int a; there is nothing on the right side of the variable name a, so it directly states that a is a variable of type int. A variable declaration has only one base type, which is the leftmost part of the descriptor. Specifiers can change the basic data type through modifiers to derive new types. Modifiers are the following four symbols: *, [], (), ^. Pointer modifier ( * ) The type is still int, and the variable name is a. But the pointer modifier ( * ) means that a is a pointer to an int value, not itself an int value. The pointer modifier ( * ) always appears to the left of a variable. Array modifier ( [] ) The array modifier ( [] ) above indicates that a is an array of ints, not a simple int value. The length of the array must be added when declaring it, for example, int a[10]; The array modifier ( [] ) always appears to the right of the variable. Function modifiers ( () ) Function modifiers mean: f is a function that returns an int value. Function modifiers can take parameters, for example, int f(long); means: f is a function that takes a long parameter and returns an int value. Function modifiers () are always on the right side of the variable. Combinations of modifiers Pointer modifier ( * ) and array modifier ( [] ) combination Modifiers can be combined to create complex variable types. Just like arithmetic operators can be combined and then the priority of the operators is determined by the priority of the operators (just like * and / have a higher priority than +/-), the same is true for modifiers. The modifiers [] and () have a higher priority than * and ^. Because [] and () have a higher priority, they are placed on the right side of the variable. Therefore, when encountering complex descriptors, you should start with the variable name (identifier), read the right part first, and then read the left part. For example Or, to improve readability, use parentheses to enclose the variable name and the part to the right. Both mean: a is a pointer array, and each element in the array points to a value of type int. Some people may ask, how can we declare a pointer to a set of int values? The following declaration can achieve this: The pointer modifier has a lower precedence than the array modifier, so it is placed in parentheses to increase its precedence. This means: a is a pointer to an array of int values. Combination of array modifier ( [] ) and function modifier () You cannot declare an array where each element is a function, nor can you declare a function that returns an array or a function. However, a function parameter can be an array. For example? The above means: f is a function with one parameter, which is an array of length 10 (each element in the array is an int value), and the function returns an int value. Combination of pointer modifier ( * ) and function modifier () Both declarations above mean: f is a function that returns a pointer to a value of type int. What if you want a pointer to a function? The above declaration means: f is a function pointer, which points to a function that returns an int value. Code block (also known as closure) modifier ( ^ ) Apple introduced this modifier in its proposed extension of the ANSI-C standard. It is called the code block pointer modifier (closure modifier). This modifier is very similar to the pointer modifier. Declaring a code block is the same as declaring a pointer to a function. This modifier can only be used for functions, so int ^a; is wrong. This explains why int ^b() is illegal and will cause a compiler error. If you read the specifier as described above, it means that b is a function and the return value is a code block pointer pointing to a value of type int. This is why ^b is enclosed in parentheses. b means: a code block pointing to a function that returns an int value or simply a code block that returns an int value. You can also pass parameters when defining code or functions, for example Means: The code block has one parameter of type long and one return value of type int. This is where code block declarations come in. In order to use code blocks in Objective-C, there are some additional syntaxes you need to remember: 1. The syntax for defining a code block; 2. How to pass a code block to an Objective-C method. Abstract Specifier An abstract specifier consists of two parts: an abstract specifier and a variable name. Abstract specifiers have three usage scenarios in standard C language:
Objective-C uses abstract specifiers as method parameters or method return values;
Here (long **) and (int *) are both abstract specifiers. So in order to use a code block as a parameter or return value in an Objective-C method, we need to find the abstract specifier of these code blocks. We can get it by removing the variable name in the specifier; For example: int (^b)() removes the variable name b to obtain the abstract specifier int (^)() and int (^b)(long) removes the variable name b to obtain the abstract specifier int (^)(long). example:
The parameter names can be omitted in the abstract specifier, because Xcode will automatically complete them for you. Block literals When you write int a = 2;, int a is a specifier and 2 is the value of a, also called the implementation. The caret (^) is also used as a unary operator to convert a function implementation into a code block. You do not need to specify the return value of the code block, it will be automatically inferred from the return statement. Because it is the implementation part of the code block, the name of the parameter needs to be defined. For example: int (^block)(long, long); the implementation is as follows
Summarize It may seem complicated, but the block syntax in Objective-C is based on the standard C syntax. A block in Objective-C is like a pointer to a function. Once you understand this and practice it a little, you will find that blocks are easy to master. |
<<: How to write a good bug report
>>: iOS A Song of Ice and Fire – Using XPC to pass the sandbox
The influence of brands has been weak for a long ...
The author of this article has reviewed and sorte...
The most important turning point is that with the...
In China, many people say that programmers are a ...
The line "When will we cut the candle in the...
What is a conversion? 1. Conversion rate Let’s ta...
Produced by: Science Popularization China Author:...
What are the WeChat public accounts for making mo...
In traffic diversion , we not only need to pursue...
On July 5, Xiaomi MIUI director Hong Feng reveale...
As a data analysis enthusiast, the author of this...
Teacher Jinchuan - Huge online community of Qianc...
In the golden autumn season, the rice in Jilin Pr...
For me, WeChat not only meets my daily communicat...
Now is the leaf-viewing season in southern my cou...