Back to Basics
Primitives
Primitives are defined by Objective-C, not by Cocoa, they are not objects, we can think about them as the atoms of Objective-C
The most basic data type is the integer or int. An integer is a whole number, that could be positive or negative. 42 and -74 are integers.
By default, variables of type int are signed, which mean that they can represent both, positive and negative values. Sometimes, when no negative values are expected, we can mark the int to just hold positive numbers, and because we free one bit of the number representation, we can hold twice as many positive numbers in a single variable.
unsigned int a = 42;
Depending on the kind of values we wish to hold in an integer variable, we can save some memory by specifying how many bits the compiler should take for each one using short, long and long long keywords.
| Specifier | Bits | Signed Range | Unsigned Range |
|---|---|---|---|
short int |
16 | -32768 ~ 32767 | 0 ~ 65535 |
int / long int |
32 | -2147483648 ~ 2147483647 | 0 ~ 4294967295 |
long long int |
64 | -9.223372036854775808 × 10^18 ~ 9.223372036854775807 × 10^18 | 0 ~ 1.8446744073709551615 × 10^19 |
Once you declare a variable, you can assign it a value with the assignment operator.
Cocoa defines two more integer types, NSInteger and NSUInteger, that are meant to replace int and unsigned int, respectively. These two types are defined as 32-bit integers in 32-platforms (older Macs and iOS devices), and 64-bit for the newer Macs.
By default, integer constants are decimal which is the most familiar notation, but you can also use other systems, like octal and hexadecimal.
| Name | Base | Prefix | Example |
|---|---|---|---|
| Octal | 8 | 0 | 52 |
| Decimal | 10 | no prefix | 42 |
| Hexadecimal | 16 | 0x | 0x2a |
The real numbers are represented by floats. Objective-C offers two different data types to hold real numbers, the float and the double. A double takes twice as many memory as a float, but can store number is a larger range, whole the float can be anything between +/- 1.5 x 10^-45 to +/- 3.4 x 10^38, a double can store numbers as small as +/- 5.0 x 10^-324 to +/- 1.7 x 10^308. Thou, not any value in these ranges can be represented in memory. As a rule of thumb, floats are reliable up to the first 7 significant digits, while doubles are accurate up to the 15th significant digit.
Apple, as almost any other platform, uses the IEEE 754 standard to implements floating point arithmetic. Due to rounding errors, you should be careful on how you use floats, they can be really big. Specially, do not try to check equality of two different floats. The subtler change in any calculation will produce really hard to find bugs.
ANSI C defines a simple variable for characters, the char. In general, a char constant is introduced with a single quotation mark.
char c = 'c';
But since char is a small int, you can also assign ASCII values to it.
char c = 99;
A string is a sequence of characters enclosed in double quotation marks.
char *hello = "Hello World!";
Because the C implementation of a string is just an array of chars, you need to be sure that the size of the array is big enough to hold the whole string. The last char in a string have to be the ASCII 0 '\0'.
Cocoa provides a class cluster called NSString (and NSMutableString), to represent an array of Unicode characters. NSString is not only able to hold more than ASCII chars, but it is much safer than pure C strings. When in doubt, use NSString. NSString has two primitive methods: -length and -characterAtIndex:, that are used as foundation for all the other methods in the interface.
Objective-C specify a boolean data type, also a small int. The BOOL type is defined to hold YES and NO. You can also use TRUE and FALSE, thou, by convention, the first are preferred.
NSLog
NSLog is a FoundationKit function for printing debug statements to the console. The first parameter is a string formatted with the desired output. NSLog understands all the specifiers used in printf, and some other specifically defined in Cocoa.
| Specifier | Description |
|---|---|
%@ |
Object |
%d ~ %i |
Signed int |
%u |
Unsigned int |
%f |
float/double |
%x ~ %X |
hexadecimal int |
%o |
octal int |
%zu |
unsigned data type (size_t) |
%p |
pointer |
%e |
float/double (in scientific notation) |
%g |
the same of %f or %e depending on the value |
%s |
C string (ASCII) |
%S |
C string (Unichar) |
%c |
char |
%C |
unichar |
%lld |
long long |
%llu |
unsigned long long |
Containers
There are times, when we need to deal with more than one element at the time. C offers, out of the box, arrays that allows to keep together a bunch of elements of the same type. Basically, a C array is just a block of memory where at runtime the values are stored.
Cocoa implements a few more advance containers, that are really helpful. NSArray, NSDictionary and NSSet.
NSSet and NSArray, are objects collections, the major difference is that the NSArray is a ordered collection, while the NSSet does not keep the elements in a given order. As been said, they can only holds objects, that means, elements that descend from NSObject.
NSDictionary is a hash map. You can associate an object to a key, to easily retrieve it later.
NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:@"object", @"key", nil];
NSLog(@"@%", [dict objectForKey:@"key"]); // -> object