Showing posts with label Objective C. Show all posts
Showing posts with label Objective C. Show all posts

Sunday, December 8, 2013

The Utilities Pane in Xcode


The Utilities pane is the column at the right of the project window. It contains inspectors that provide information about the current selection or its settings; if those settings can be changed, this is where you change them. It also contains libraries that function as a source of objects you may need while editing your project. The Utilities pane’s impor‐ tance emerges mostly when you’re editing a .storyboard or .xib file. But it can be useful also while editing code, because Quick Help, a form of documentation , is displayed here as well, plus the Utilities pane is the source of code snippets. To toggle the visibility of the Utilities pane, choose View → Utilities → Hide/Show Utilities (Command-Option-0). You can change the Utilities pane’s width by dragging the vertical line at its left edge.
The Utilities pane consists of numerous palettes, which are clumped into multiple sets, which are themselves divided into two major groups: the top half of the pane and the bottom half of the pane. You can change the relative heights of these two halves by dragging the horizontal line that separates them.
The top half
What appears in the top half of the Utilities pane depends on what’s selected in the current editor. There are three main cases:
A code file is being edited
The top half of the Utilities pane shows either the File inspector or Quick Help. Toggle between them with the icons at the top of this half of the Utilities pane, or with their keyboard shortcuts (Command-Option-1, Command-Option-2). The File inspector is rarely needed, but Quick Help can be useful as documen‐ tation. The File inspector consists of multiple sections, each of which can be expanded or collapsed by clicking its header.
A .storyboard or .xib file is being edited
The top half of the Utilities pane shows, in addition to the File inspector and Quick Help, the Identity inspector (Command-Option-3), the Attributes in‐ spector (Command-Option-4), the Size inspector (Command-Option-5), and the Connections inspector (Command-Option-6). These can consist of mul‐ tiple sections, each of which can be expanded or collapsed by clicking its header.
An asset catalog is being edited
In addition to the File inspector and Quick Help, the Attributes inspector (Command-Option-4) lets you determine which variants of an image are listed.
The bottom half
The bottom half of the Utilities pane shows one of four libraries. Toggle between them with the icons at the top of this half of the Utilities pane, or with their keyboard shortcuts. They are the File Template library (Command-Option-Control-1), the Code Snippet library (Command-Option-Control-2), the Object library (Command-Option-Control-3), and the Media library (Command-Option- Control-4). The Object library is the most important; you’ll use it heavily when editing a .storyboard or .xib file.
To see a help pop-up describing the currently selected item in a library, press Spacebar. 

Wednesday, December 4, 2013

Pointer Parameters and the Address Operator


Objective-C is chock-a-block with pointers (and asterisks), because that’s how Objective-C refers to an object. Objective-C methods typically work with objects, so they typically expect pointer parameters and return a pointer value. But this doesn’t make things more complicated. Pointers are what Objective-C expects, but pointers are also what Objective-C gives you. Pointers are exactly what you’ve got, so there’s no problem.

For example, one way to concatenate two NSStrings is to call the NSString method stringByAppendingString:, which the documentation tells you is declared as follows:
    - (NSString *)stringByAppendingString:(NSString *)aString

This declaration is telling you (after you allow for the Objective-C syntax) that this method expects one NSString* parameter and returns an NSString*. That sounds messy, but it isn’t, because every NSString is really an NSString*. So nothing could be simpler than to obtain a new NSString consisting of two concatenated NSStrings:
    NSString* s1 = @"Hello, ";
    NSString* s2 = @"World!";
    NSString* s3 = [s1 stringByAppendingString: s2];

Sometimes, however, a function or method expects as a parameter a pointer to a thing, but what you’ve got is not that pointer but the thing itself. Thus, you need a way to create a pointer to that thing. The solution is the address operator (K&R 5.1), which is an ampersand before the name of the thing.
For example, there’s an NSString method for reading from a file into an NSString, which is declared like this:
    + (id)stringWithContentsOfFile:(NSString *)path
                          encoding:(NSStringEncoding)enc
                             error:(NSError **)error	
Never mind for now what an id is, and don’t worry about the Objective-C method declaration syntax. Just consider the types of the parameters. The first one is an NSString*; that’s no problem, as every reference to an NSString is actually a pointer to an NSString. An NSStringEncoding turns out to be merely an alias to a primitive data type, an NSUInteger, so that’s no problem either. But what on earth is an NSError**?
By all logic, it looks like an NSError** should be a pointer to a pointer to an NSError. And that’s exactly what it is. This method is asking to be passed a pointer to a pointer to an NSError. Well, it’s easy to declare a pointer to an NSError:
    NSError* err;
But how can we obtain a pointer to that? With the address operator! So our code might look, schematically, like this:
    NSString* path = // something or other
    NSStringEncoding enc = // something or other
    NSError* err = nil;
    NSString* result =[NSString stringWithContentsOfFile: path encoding: enc error: &err];
The important thing to notice is the ampersand. Because err is a pointer to an NSError, &err is a pointer to a pointer to an NSError, which is just what we’re expected to provide. Thus, everything goes swimmingly.
You can use the address operator to create a pointer to any named variable. A C function is technically a kind of named variable, so you can even create a pointer to a function! This is an example of when you’d use the name of the function without the parentheses: you aren’t calling the function, you’re talking about it. For example, &square is a pointer to the square function. Moreover, just as the bare name of an array is implicitly a pointer to its first element, the bare name of a function is implicitly a pointer to the function; the address operator is optional.

Functions


C is a function-based language. A function is a block of code defining what should happen; when other code calls (invokes) that function, the function’s code does happen. A function returns a value, which is substituted for the call to that function.

Here’s a definition of a function that accepts an integer and returns its square:
    int square(int i) {
        return i * i;
}
Now I’ll call that function:
int i = square(3);
Because of the way square is defined, that is exactly like saying:
int i = 9;
That example is extremely simple, but it illustrates many key aspects of functions. Let’s analyze how a function is defined:
int(1) square(2) ((3) int i) {(4)return i * i;
}

Note: The Text in red color is explained below.

(1) We start with the type of value that the function returns; here, it returns an int. 
(2) Then we have the name of the function, which is square.
(3) Then we have parentheses, and here we place the data type and name of any values that this function expects to receive. Here, square expects to receive one value, an int, which we are calling i. The name i (along with its expected data type) is a parameter; when the function is called, its value will be supplied as an argument. If a function expects to receive more than one value, multiple parameters in its definition are separated by a comma (and when the function is called, the arguments supplied are likewise separated by a comma).
(4) Finally, we have curly braces containing the statements that are to be executed when the function is called.


Those curly braces constitute a scope; variables declared within them are local to the function. The names used for the parameters in the function definition are also local to the function; in other words, the i in the first line of the function definition is the same as the i in the second line of the function definition, but it has nothing to do with any i used outside the function definition (as when the result of the function call is assigned to a variable called i). The value of the i parameter in the function definition is assigned from the corresponding argument when the function is called; in the previous example, it is 3, which is why the function result is 9. Supplying a function call with arguments is thus a form of assignment. Suppose a function is defined like this:
    int myfunction(int i, int j) { // ...
And suppose we call that function:
int result = myfunction(3, 4);
That function call effectively assigns 3 to the function’s i parameter and 4 to the func‐
tion’s j parameter.
When a return statement is encountered, the value accompanying it is handed back as the result of the function call, and the function terminates. It is legal for a function to return no value; in such a case, the return statement has no accompanying value, and the definition states the type of value returned by the function as void. It is also legal to call a function and ignore its return value even if it has one. For example, we could say:
square(3);
That would be a somewhat silly thing to say, because we have gone to all the trouble of calling the function and having it generate the square of 3 — namely 9 — but we have done nothing to capture that 9. It is exactly as if we had said:
9;
You’re allowed to say that, but it doesn’t seem to serve much purpose. On the other hand, the point of a function might be not so much the value it returns as other things it does as it is executing, so then it might make perfect sense to ignore its result.

The parentheses in a function’s syntax are crucial. Parentheses are how C knows there’s a function. Parentheses after the function name in the function definition are how C knows this is a function definition, and they are needed even if this function takes no parameters. Parentheses after the function name in the function call are how C knows this is a function call, and they are needed even if this function call supplies no argu‐ ments. Using the bare name of a function is possible, because the name is the name of something, but it doesn’t call the function. (I’ll talk later about something it does do.)
Let’s return to the simple C function definition and call that I used as my example earlier. Suppose we combine that function definition and the call to that function into a single program:
    int square(int i) {
        return i * i;
    }
    int i = square(3);
That is a legal program, but only because the definition of the square function precedes the call to that function. If we wanted to place the definition of the square function elsewhere, such as after the call to it, we would need at least to precede the call with a declaration of the square function (Example 1-3). The declaration looks just like the first line of the definition, but it is a statement, ending with a semicolon rather than a left curly brace.
Example 1-3. Declaring, calling, and defining a function
int square(int i);
int i = square(3);
int square(int i) {
return i * i; }
The parameter names in the declaration do not have to match the parameter names in the definition, but all the types (and, of course, the name of the function) must match. The types constitute the signature of this function. In other words, it does not matter if the first line, the declaration, is rewritten thus:
    int square(int j);
What does matter is that, both in the declaration and in the definition, square is a function taking one int parameter and returning an int. (In a modern Objective-C pro‐ gram, though, the function declaration usually won’t be necessary, even if the function call precedes its definition; see “Modern Objective-C Function and Method Declara‐ tions”)
In Objective-C, when you’re sending a message to an object, you won’t use a function call; you’ll use a method call. But you will most definitely use plenty of C function calls as well. For example, earlier we initialized a CGPoint by setting its x element and its y element, but what you’ll usually do to make a new CGPoint is to call CGPointMake, which is declared like this:
    CGPoint CGPointMake (
       CGFloat x,
CGFloat y );
Despite its multiple lines and its indentations, this is indeed a C function declaration, just like the declaration for our simple square function. It says that CGPointMake is a C function that takes two CGFloat parameters and returns a CGPoint. So now you know (I hope) that it would be legal (and typical) to write this sort of thing:
    CGPoint myPoint = CGPointMake(4.3, 7.1); 

 
 
 

Operators


Arithmetic operators are straightforward, but watch out for the rule that “integer division truncates any fractional part.” This rule is the cause of much novice error in C. If you have two integers and you want to divide them in such a way as to get a fractional result, you must represent at least one of them as a float:
    int i = 3;
    float f = i/2; // beware! not 1.5
To get 1.5, you should have written i/2.0 or (float)i/2.
The integer increment and decrement operators , ++ and --, work differently depending on whether they precede or follow their variable. The expression ++i replaces the value of i by 1 more than its current value and then uses the resulting value; the expression i++ uses the current value of i and then replaces it with 1 more than its current value. This is one of C’s coolest features.
C also provides bitwise operators , such as bitwise-and (&) and bitwise-or (|); they operate on the individual binary bits that constitute integers. You are most likely to need bitwise-or, because the Cocoa API often uses bits as switches when multiple options are to be specified simultaneously. For example, when specifying how a UIView is to be animated, you are allowed to pass an options argument whose value comes from the UIViewAnimationOptions enumeration, whose definition begins as follows:
    typedef NS_OPTIONS(NSUInteger, UIViewAnimationOptions) {
    UIViewAnimationOptionLayoutSubviews
    UIViewAnimationOptionAllowUserInteraction
    UIViewAnimationOptionBeginFromCurrentState
    UIViewAnimationOptionRepeat
    UIViewAnimationOptionAutoreverse
// ... };
= 1 <<  0,
= 1 <<  1,
= 1 <<  2,
= 1 <<  3,
= 1 <<  4,
The << symbol is the left shift operator; the right operand says how many bits to shift the left operand. So pretend that an NSUInteger is 8 bits (it isn’t, but let’s keep things simple and short). Then this enumeration means that the following name–value pairs are defined (using binary notation for the values):
UIViewAnimationOptionLayoutSubviews
    00000001
UIViewAnimationOptionAllowUserInteraction
    00000010
UIViewAnimationOptionBeginFromCurrentState
    00000100
UIViewAnimationOptionRepeat
    00001000
UIViewAnimationOptionAutoreverse
    00010000
The reason for this bit-based representation is that these values can be combined into a single value (a bitmask) that you pass to set the options for this animation. All Cocoa has to do to understand your intentions is to look to see which bits in the value that you pass are set to 1. So, for example, 00011000 would mean that UIViewAnimationOption- Repeat and UIViewAnimationOptionAutoreverse are both true (and that the others, by implication, are all false).
The question is how to form the value 00011000 in order to pass it. You could just do the math, figure out that binary 00011000 is decimal 24, and set the options argument to 24, but that’s not what you’re supposed to do, and it’s not a very good idea, because it’s error-prone and makes your code incomprehensible. Instead, use the bitwise-or operator to combine the desired options:
    (UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse)
This notation works because the bitwise-or operator combines its operands by setting in the result any bits that are set in either of the operands, so 00001000 | 00010000 is 00011000, which is just the value we’re trying to convey. (And how does the runtime parse the bitmask to discover whether a given bit is set? With the bitwise-and operator.)
Simple assignment is by the equal sign. But there are also compound as‐ signment operators that combine assignment with some other operation. For example:
height *= 2; // same as saying: height = height * 2; The ternary operator (?:) is a way of specifying one of two values depending on a
condition. The scheme is as follows:
(condition) ? exp1 : exp2
If the condition is true (see the next section for what that means), the expression exp1 is evaluated and the result is used; otherwise, the expression exp2 is evaluated and the result is used. For example, you might use the ternary operator while performing an assignment, using this schema:
myVariable = (condition) ? exp1 : exp2;
What gets assigned to myVariable depends on the truth value of the condition. There’s nothing happening here that couldn’t be accomplished more verbosely with flow con‐ trol, but the ternary operator can greatly improve clarity, and I use it a lot.

Arrays ( Learn C Programming )


A C array (K&R 5.3) consists of multiple elements of the same data type. An array declaration states the data type of the elements, followed by the name of the array, along with square brackets containing the number of elements:

    int arr[3]; // means: arr is an array consisting of 3 ints

To refer to an element of an array, use the array’s name followed by the element number in square brackets. The first element of an array is numbered 0. So we can initialize an array by assigning values to each element in turn:

    int arr[3];
    arr[0] = 123;
    arr[1] = 456;
    arr[2] = 789;

Alternatively, you can initialize an array at declaration time by assigning a list of values in curly braces, just as with a struct. In this case, the size of the array can be omitted from the declaration, because it is implicit in the initialization (K&R 4.9):
    int arr[] = {123, 456, 789};
Curiously, the name of an array is the name of a pointer (to the first element of the array). Thus, for example, having declared arr as in the preceding examples, you can use arr wherever a value of type int* (a pointer to an int) is expected. This fact is the basis of some highly sophisticated C idioms that you almost certainly won’t need to know about (which is why I don’t recommend that you read any of K&R Chapter 5 beyond section 3).
Here’s an example where a C array might be useful when programming iOS. The func‐ tion CGContextStrokeLineSegments is declared like this:
Arrays in C programming
        Figure 1-1. Pointers and assignment

 void CGContextStrokeLineSegments (
       CGContextRef c,
       const CGPoint points[],
       size_t count
);

The second parameter is a C array of CGPoints. That’s what the square brackets tell you. So to call this function, you’d need to know at least how to make an array of CGPoints. You might do it like this: 

CGPoint arr[] = {{4,5}, {6,7}, {8,9}, {10,11}};
Having done that, you can pass arr as the second argument in a call to CGContextStroke-
LineSegments.
Also, a C string, as I’ve already mentioned, is actually an array. For example, the NSString method stringWithUTF8String: takes (according to the documentation) “a NULL- terminated C array of bytes in UTF8 encoding;” but the parameter is declared not as an array, but as a char*. Those are the same thing, and are both ways of saying that this method takes a C string.
(The colon at the end of the method name stringWithUTF8String: is not a misprint; many Objective-C method names end with a colon. 

Tuesday, December 3, 2013

Pointers ( Learn C Programming)


The other big way that C extends its range of data types is by means of pointers (K&R 5.1). A pointer is an integer (of some size or other) designating the location in memory where the real data is to be found. Knowing the structure of that real data and how to work with it, as well as allocating a block of memory of the required size beforehand and disposing of that block of memory when it’s no longer needed, is a very complicated business. Luckily, this is exactly the sort of complicated business that Objective-C is going to take care of for us. So all you really have to know to use pointers is what they are and what notation is used to refer to them.
Let’s start with a simple declaration. If we wanted to declare an integer in C, we could say:
int i;
That line says, “i is an integer.” Now let’s instead declare a pointer to an integer:
int* intPtr;
That line says, “intPtr is a pointer to an integer.” Never mind how we know there really is going to be an integer at the address designated by this pointer; here, I’m concerned only with the notation. It is permitted to place the asterisk in the declaration before the name rather than after the type:
int *intPtr;
You could even put a space on both sides of the asterisk (though this is rarely done):
int * intPtr;
I prefer the first form, but I do occasionally use the second form, and Apple quite often uses it, so be sure you understand that these are all ways of saying the same thing. No matter how the spaces are inserted, the name of the type is still int*. If you are asked what type intPtr is, the answer is int* (a pointer to an int); the asterisk is part of the name of the type of this variable. If you needed to cast a variable p to this type, you’d cast like this:(int*)p. Once again, it is possible that you’ll see code where there’s a space before the asterisk, like this: (int *)p.
The most general type of pointer is pointer-to-void (void*), the generic pointer. It is legal to use a generic pointer wherever a specific type of pointer is expected. In effect, pointer- to-void casts away type checking as to what’s at the far end of the pointer. Thus, the following is legal:
    int* p1; // and pretend p1 has a value
    void* p2;
    p2 = p1;
    p1 = p2;
Pointers are very important in Objective-C, because Objective-C is all about objects (Chapter 2), and every variable referring to an object is itself a pointer. In effect, Objective-C takes advantage of the fact that a C pointer can designate real data whose nature and bookkeeping are arbitrary. In this case, that real data is an Objective-C object. Objective-C knows what this means, but you generally won’t worry about it — you’ll just work with the C pointer and let Objective-C take care of the details. For example, I’ve already mentioned that the Objective-C string type is called NSString. So the way to declare an NSString variable is as a pointer to an NSString:
NSString* s;
An NSString literal is an NSString value, so we can even declare and initialize this NSString object, thus writing a seriously useful line of Objective-C code:
    NSString* s = @"Hello, world!";
In pure C, having declared a pointer-to-integer called intPtr, you are liable to speak later in your code of *intPtr. This notation, outside of a declaration, means “the thing pointed to by the pointer intPtr.” You speak of *intPtr because you wish to access the integer at the far end of the pointer; this is called dereferencing the pointer.
But in Objective-C, this is generally not the case. In your code, you’ll be treating the pointer to an object as the object; you’ll never dereference it. So, for example, having declared s as a pointer to an NSString, you will not then proceed to speak of *s; rather, you will speak simply of s, as if it were the string. All the Objective-C stuff you’ll want to do with an object will expect the pointer, not the object at the far end of the pointer; behind the scenes, Objective-C itself will take care of the messy business of following the pointer to its block of memory and doing whatever needs to be done in that block of memory. This fact is extremely convenient for you as a programmer, but it does cause Objective-C users to speak a little loosely; we tend to say that “s is an NSString,” when of course it is actually a pointer to an NSString.
The logic of how pointers work, both in C and in Objective-C, is different from the logic of how simple data types work. The difference is particularly evident with assignment.
Assignment to a simple data type changes the data value. Assignment to a pointer re‐ points the pointer. Suppose ptr1 and ptr2 are both pointers, and you say:
ptr1 = ptr2;
Now ptr1 and ptr2 are pointing at the same thing. Any change to the thing pointed to by ptr1 will also change the thing pointed to by ptr2, because they are the same thing. Meanwhile, whatever ptr1 was pointing to before the assignment is now not being pointed to by ptr1; it might, indeed, be pointed to by nothing (which could be bad). A firm understanding of these facts is crucial when working in Objective-C.

Structs (Learn C Programming)


C offers few simple native data types, so how are more complex data types made? There are three ways: structures, pointers, and arrays. Both structures and pointers are going to be crucial when you’re programming iOS. C arrays are needed less often, because Objective-C has its own NSArray object type.
A C structure, usually called a struct (K&R 6.1), is a compound data type: it combines multiple data types into a single type, which can be passed around as a single entity.
Moreover, the elements constituting the compound entity have names and can be ac‐ cessed by those names through the compound entity, using dot-notation. The iOS API has many commonly used structs, typically accompanied by convenience functions for working with them.
For example, the iOS documentation tells you that a CGPoint is defined as follows:
    struct CGPoint {
       CGFloat x;
       CGFloat y;
    };
    typedef struct CGPoint CGPoint;
Recall that a CGFloat is basically a float, so this is a compound data type made up of two simple native data types; in effect, a CGPoint has two CGFloat parts, and their names are x and y. (The rather odd-looking last line merely asserts that one can use the term CGPoint instead of the more verbose struct CGPoint.) So we can write:
    CGPoint myPoint;
    myPoint.x = 4.3;
    myPoint.y = 7.1;
Just as we can assign to myPoint.x to set this part of the struct, we can say myPoint.x to get this part of the struct. It’s as if myPoint.x were the name of a variable. Moreover, an element of a struct can itself be a struct, and the dot-notation can be chained. To illustrate, first note the existence of another iOS struct, CGSize:
    struct CGSize {
       CGFloat width;
       CGFloat height;
    };
    typedef struct CGSize CGSize;
Put a CGPoint and a CGSize together and you’ve got a CGRect:
    struct CGRect {
       CGPoint origin;
       CGSize size;
    };
    typedef struct CGRect CGRect;
So suppose we’ve got a CGRect variable called myRect, already initialized. Then myRect.origin is a CGPoint, and myRect.origin.x is a CGFloat. Similarly, myRect.size is a CGSize, and myRect.size.width is a CGFloat. You could change just the width part of our CGRect directly, like this:
    myRect.size.width = 8.6; 
Instead of initializing a struct by assigning to each of its elements, you can initialize it at declaration time by assigning values for all its elements at once, in curly braces and separated by commas, like this:
CGPoint myPoint = { 4.3, 7.1 }; 
    CGRect myRect = { myPoint, {10, 20} };

You don’t have to be assigning to a struct-typed variable to use a struct initializer; you can use an initializer anywhere the given struct type is expected, but you might also have to cast to that struct type in order to explain to the compiler what your curly braces mean, like this:
    CGContextFillRect(con, (CGRect){myPoint, {10, 20}}); 
In that example, CGContextFillRect is a function. I’ll talk about functions later in this chapter, but the upshot of the example is that what comes after the first comma has to be a CGRect, and can therefore be a CGRect initializer provided it is accompanied by a CGRect cast. 

Variable Declaration, Initialization, and Data Types (Learn C Programming)


C is a strongly typed language. Every variable must be declared, indicating its data type, before it can be used. Declaration can also involve explicit initialization, giving the variable a value; a variable that is declared but not explicitly initialized is of uncertain value (and should be regarded as dangerous until it is initialized). In K&R C, declarations must precede all other statements, but in modern versions of C, this rule is relaxed so that you don’t have to declare a variable until just before you start using it:
int height = 2;
    int width = height * 2;
    height = height + 1; 
    int area = height * width;

The basic built-in C data types are all numeric: char (one byte), int (four bytes), float and double (floating-point numbers), and varieties such as short (short integer), long (long integer), unsigned short, and so on. A numeric literal may optionally express its type through a suffixed letter or letters: for example, 4 is an int, but 4UL is an unsigned long; 4.0 is a double, but 4.0f is a float. Objective-C makes use of some further numeric types derived from the C numeric types (by way of the typedef statement, K&R 6.7) designed to respond to the question of whether the processor is 64-bit; the most im‐ portant of these are NSInteger (along with NSUInteger) and CGFloat. You don’t need to use them explicitly unless an API tells you to, and even when you do, just think of NSInteger as int and CGFloat as float, and you’ll be fine.
To cast (or typecast) a variable’s value explicitly to another type, precede the variable’s name with the other type’s name in parentheses:
    int height = 2;
    float fheight = (float)height;
In that particular example, the explicit cast is unnecessary because the integer value will be cast to a float implicitly as it is assigned to a float variable, but it illustrates the notation. You’ll find yourself typecasting quite a bit in Objective-C, mostly to subdue the worries of the compiler.
Another form of numeric initialization is the enumeration, or enum (K&R 2.3). It’s a way of assigning names to a sequence of numeric values and is useful when a value represents one of several possible options. The Cocoa API uses this device a lot. For example, the three possible types of status bar animation might be defined like this:
    typedef enum {
       UIStatusBarAnimationNone,
       UIStatusBarAnimationFade,
       UIStatusBarAnimationSlide,
    } UIStatusBarAnimation;
That definition assigns the value 0 to the name UIStatusBarAnimationNone, the value 1 to the name UIStatusBarAnimationFade, and the value 2 to the name UIStatusBar- AnimationSlide. The upshot is that you can use the suggestively meaningful names without caring about, or even knowing, the arbitrary numeric values they represent. It’s a useful idiom, and you may well have reason to define enumerations in your own code.
That definition also assigns the name UIStatusBarAnimation to this enumeration as a whole. A named enumeration is not a data type, but you can pretend that it is, and the compiler can warn you if you mix enumeration types. For example, suppose you were to write this code: 

UIStatusBarAnimation anim = UIInterfaceOrientationPortrait;
That isn’t illegal; UIInterfaceOrientationPortrait is another name for 0, just as if you had said UIStatusBarAnimationNone. However, it comes from a different named enumeration, namely UIInterfaceOrientation. The compiler detects this, and warns you. Just as with a real data type, you can even squelch that warning by typecasting.
In iOS 7, the status bar animation types are defined like this:
    typedef NS_ENUM(NSInteger, UIStatusBarAnimation) {
        UIStatusBarAnimationNone,
        UIStatusBarAnimationFade,
        UIStatusBarAnimationSlide,
};
That notation was introduced in LLVM compiler version 4.0, which made its debut in Xcode 4.4. NS_ENUM is a macro, a form of preprocessor text substitution discussed at the end of this chapter; when the text substitution is performed, that code turns out to be shorthand for this:
    typedef enum UIStatusBarAnimation : NSInteger UIStatusBarAnimation;
    enum UIStatusBarAnimation : NSInteger {
        UIStatusBarAnimationNone,
        UIStatusBarAnimationFade,
        UIStatusBarAnimationSlide,
};
That looks almost exactly like the old way of expressing the same enumeration, but the new way involves some notation that isn’t part of standard C, telling the compiler what variety of integer value is being used here (it’s an NSInteger). This makes UIStatusBar‐ Animation even more like a genuine data type; in addition, the new enum notation lets Xcode help you more intelligently when performing code completion, as discussed in Chapter 9. Another macro, NS_OPTIONS, evaluates in Objective-C as a synonym of NS_ENUM (they are distinct only in C++ code, which is not discussed in this book).
There appears to be a native text type (a string) in C, but this is something of an illusion; behind the scenes, it is a null-terminated array of char. For example, in C you can write a string literal like this:
"string"
But in fact this is stored as 7 bytes, the numeric (ASCII) equivalents of each letter fol‐ lowed by a byte consisting of 0 to signal the end of the string. This data structure, called a C string, is rarely encountered while programming iOS. In general, when working with strings, you’ll use an Objective-C object type called NSString. An NSString is totally different from a C string; it happens, however, that Objective-C lets you write a literal NSString in a way that looks very like a C string:
@"string" 

Notice the at-sign! This expression is actually a directive to the Objective-C compiler to form an NSString object. A common mistake is forgetting the at-sign, thus causing your expression to be interpreted as a C string, which is a completely different animal.
Because the notation for literal NSStrings is modeled on the notation for C strings, it is worth knowing something about C strings, even though you won’t generally encounter them. For example, K&R lists a number of escaped characters (K&R 2.3), which you can also use in a literal NSString, including the following:

\n
A Unix newline character

\t 

A tab character

\"
A quotation mark (escaped to show that this is not the end of the string literal)

\\
A backslash 


K&R also mention a notation for concatenating string literals, in which multiple string literals separated only by white space are automatically concatenated and treated as a single string literal. This notation is useful for splitting a long string into multiple lines for legibility, and Objective-C copies this convention for literal NSStrings as well, except that you have to remember the at-sign:
    @"This is a big long literal string "
    @"which I have broken over two lines of code.";