iOS100

iOS Platform Development Introduction


Objective-C Basics 

Flow Control, Data Types & Foundation Structures

Comments

  • To create a comment, start the comment with two forward slashes.
 // This is a comment
  • Multiple line comments...

 
 /* This is a comment
    extending over two lines */
	
	/* 
	 * This is a comment expanding over...
	 * One...
	 * Two...
	 * 4 + 2 (Above and Below) = 6 lines!
	 */ 
	 
	/* 
		Anything can go between these lines! 
	*/

Variables

  •  Allow us to temporarily store data.
  • Act as containers that hold various types of data and can be manipulated in various ways.
  • Here are several of the most important variables that you should know:
    • int - for storing integers (numbers with no decimal point)
    • char - for storing a single character
    • float - for storing numbers with decimal points
    • double - same as a float but double the accuracy

Outputting Data

How do we display variable values as output? 
Lets say we want to output the sum of the following equation:

int x = 1;
int y = 2;
int sum;

sum = x + y; 

In this case sum is equal to the value of 1 + 2 which is 3.

Outputting Data Continued...

To output the value of sum we must use what is called a format specifier. 

The most basic format specifiers include:

  • %i - integer
  • %f - float
  • %e - double
  • %c - char
   
Format specifiers are used in the following fashion:
NSLog(@"The sum of x + y = %i", sum); 
 "The sum of x + y = 3".

Outputting Data Continued...

NSLog(@"The sum of %i + %i = %i", x, y, sum); 
In this case, we are choosing to substitute the variables x and y with their actual values in the output 

"The sum of 1 + 2 = 3".

If we changed the NSLog statement to be the following:
NSLog(@"The sum of %i + %i = %i", y, x, sum); 
 "The sum of 2 + 1 = 3"





Operators

The Basic Assignment Operator (=)

The following examples are all valid uses of the assignment operator:
int x;

x = 10;
x = y + z;
x = y;    

Assignment operators can also be chained to assign the same value to multiple variables. 
int x, y, z;
x = y = z = 10; 

Arithmetic Operators

Modulo?

The result of the % operator is the remainder from the integer division of the first operand by the second.

int x = 13, y = 5, remainder;
remainder =  x % y; 
// remainder = 3 

5 goes into 13 fully only 2 times (5 * 2 = 10)

The remaining 3 (13 - 10 = 3) is the result.

Modulo Continued...

One common use for modulo is to determine if an integer is odd or even. If it is even, then a modulus of two will equal zero. Otherwise it will equal another value.


 int anInt;

//Some code that sets the value of anInt

if ((anInt % 2) == 0) { 
    NSLog(@"anInt is even");
} else {
    NSLog(@"anInt is odd");
}

Order of Precedence...

Note that multiple operators may be used in a single expression. 

For example:
x = y * 10 + z - 5 / 4; 

While the above code is perfectly valid it is important to be aware that Objective-C does not evaluate the expression from left to right or right to left, but rather in an order specified by the precedence of the various operators. 

(As specified in the previous table, highest precedence to lowest)

Compound Assignment Operators


Increment and Decrement Operators


x++; Increment x by 1
x--; Decrement x by 1 

int x = 9;
int y;
y = ++x; // y = 10

int x = 9;
int y;
y = x--;
// y = 9 
// x = 8 

Comparison Operators


Boolean Logical Operators

 
Key operators are:

NOT (!)
AND (&&)
OR (||)
XOR (^)


Boolean Logical Operators Continued...


bool flag = true; //variable is true
bool secondFlag;

secondFlag = !flag; // secondFlag set to false

if ((10 < 20) || (20 < 10))
    NSLog (@"Expression is true"); 

if ((10 < 20) && (20 < 10))
  NSLog (@"Expression is true"); 

if ((10 < 20) ^ (20 < 10))
  NSLog (@"Expression is true"); 

The Ternary Operator


A shortcut way of making decisions...

[condition] ? [true expression] : [false expression] 

int x = 10;
int y = 20;

NSLog(@"Largest number is %i", x > y ? x : y );

// Largest number is 20 



Conditionals & Loops


if else




if (condition) {
    // statement(s) if the condition is true;
} else {
    // statement(s) if the condition is not true;
} 

for



for (counter; condition; update counter) {
    // statement(s) to execute while the condition is true;
}

// Example
for (int i = 0; i < 5; i++){
    NSLog(@"%i", i);
}


for in

for (Type newVariable in expression ) {
    // statement(s); 
}

// or

Type existingVariable;for (existingVariable in expression) {
    // statement(s);
} 

// Example
for (NSString* currentString in myArrayOfStrings)
{
    NSLog(currentString);
}

// Equivalent to...
for (int i = 0; i < [myArrayOfStrings count]; i++)
{
    NSLog([myArrayOfStrings objectAtIndex:i]);
}

while


while (condition) { 
    // statement(s) to execute while the condition is true 
}  

// Example

int myCount = 0;

while ( myCount < 100 )
{
      myCount++;
      NSLog(@"myCount = %i", myCount);
}

// Prints 1 - 100
// Why not 1 - 99?

do while



do {
    // statement(s) to execute while the condition is true 
} while (condition); 

// Example

int i = 10;

do
{
       NSLog(@"%i", i);
       i--;
} while (i > 0);

// What should we see here?

Jump statements



  • return; 
    • Stop execution and returns to the calling function.
  • break; 
    • Leave a loop.
  • continue; 
    • Skip the rest of the loop and start the next iteration.





Primitive Data Types


Booleans

  • Objective-C programs use the BOOL data type to store Boolean values. 
  • Objective-C also defines its own true and false keywords, which are YES and NO, respectively. 

To display BOOL values via NSLog(), use %i in the format string:

BOOL isHuman = NO;
NSLog(@"It's alive: %i", isHuman); 

The %i specifier is used to display integers, so this should output It's alive: 0.

Char


Denotes a single-byte signed integer, and can be used to store values between -128 and 127 or an ASCII character. 


To display a char as an integer, just use the generic %i specifier introduced in the previous code sample. To format it as an ASCII character, use %c:

char letter = 'z';
NSLog(@"The ASCII letter %c is actually the number %i", letter, letter);; 

Integers

  • Short Integers
short int littleInt = 27000;
NSLog(@"The short int is: %hi", littleInt); 
  • Normal Integers
int normalInt = 1234567890;
NSLog(@"The normal integer is: %i", normalInt); 
  • Long Integers
long int bigInt = 9223372036854775807;
NSLog(@"The big integer is: %li", bigInt); 


Note: The idea behind having so many integer data types is to give developers the power to balance their program's memory footprint versus its numerical capacity.

Floats & Doubles

Literal values should be suffixed with f to mark the value as single precision instead of a double.
float someRealNumber = 0.42f;
NSLog(@"The floating-point number is: %f", someRealNumber); 
 
%5.3f will display 3 digits after the decimal and pad the result so there are 5 places total.
double anotherRealNumber = 0.42;
NSLog(@"The floating-point number is: %5.3f", anotherRealNumber);

(useful for aligning the decimal point when listing values).

Important Note on Floats & Doubles


  • Intrinsically not precise. 
  • Careful consideration must be paid to comparing floating-point values, and they should never be used to record precision-sensitive data (e.g., money). 
  • For representing fixed-point values in Objective-C, you should use NSDecimalNumber which is a Foundation Data Structure.

Structs

Objective-C also provides access to C structs, which can be used to define custom data structures.
typedef struct { float x; float y; } Point2D; 
Point2D p1 = {10.0f, 0.5f};
NSLog(@"The point is at: (%.1f, %.1f)", p1.x, p1.y); 
The {10.0f, 0.5f} notation is called a compound literal, and it can be used to initialize a struct. After initialization, you can also assign new values to a struct's properties with the = operator:
p1.x = -2.5f;
p1.y = 2.5f; 
Great for performance, but you're usually better off storing custom data structures in a full-fledged class.

Arrays

C arrays are a contiguous block of memory allocated when they're declared, and all of their elements must be of the same type.
int someValues[5] = {15, 32, 49, 90, 14};
for (int i=0; i<5; i++) {
    NSLog(@"The value at index %i is: %i", i, someValues[i]);
} 
Individual elements can be accessed by passing the item number in square brackets

Pointers

You can access array elements via pointers.

Pointers provide a low-level way to directly access memory addresses in a C program. And, since C arrays are just contiguous blocks of memory, pointers are a natural way to interact with items in an array.

Pointers are created by prefixing the variable name with an asterisk (*). 
int someValues[5] = {15, 32, 49, 90, 14};
int *pointer = someValues; 

Pointers Continued...


int someValues[5] = {15, 32, 49, 90, 14};
int *pointer = someValues;  
By default, a pointer points contains the memory location to the first item in the array.

To get the underlying value out of the memory address, we need to dereference the pointer using the asterisk operator.
NSLog(@"The first value is: %i", *pointer); 

Pointers Continued...

You can increment (++) and decrement (--) pointers to move memory addresses.
pointer++;
NSLog(@"The next value is: %i", *pointer); 
 Since an array is a contiguous block of memory, the pointer will now rest at the address of the second element of the array. 
for (int i=0; i<5; i++) {
    pointer++;
    NSLog(@"The value at index %i is: %i", i, *pointer);
} 
Pointers are  very important to Objective-C programs. 
Every object is referenced through a pointer!

void, nil, & NULL

  • The void type represents the absence of a value. Void is used with functions and methods that don't return a value.
- (void)sayHello; 
  • The nil and NULL keywords are both used to represent empty pointers. 
  • The nil constant should only be used as an empty value for Objective-C objects
  • NULL can be used for either primitive pointers or Objective-C object pointers, though nil is the preferred choice




Objective-C Basics

Calling Methods

  • A method is a section of code that we can call from elsewhere in our code.

  • Basic syntax for calling a method on an object:

[object method];
[object methodWithInput:input];
  • Methods can return a value:

  • output = [object methodWithOutput];
    output = [object methodWithInputAndOutput:input];

    Calling Methods Continued...

    • Methods can be called on classes too!
    • In the example below, we call the string method on the NSString class, which returns a new NSString object:
    NSString *myString = [NSString string];
    • This is now an NSString variable, so the compiler will warn us if we try to use a method on this object which NSString doesn't support.
    • Notice that there's a asterisk to the right of the object type. All Objective-C object variables are pointers types.

    Nested Methods

    • In many languages, nested method or function calls look like this:
    function1 ( function2() ); 
    • The result of function2 is passed as input to function1. In Objective-C, nested methods look like this:
    [NSString stringWithFormat:[prefs format]]; 

    Avoid nested nesting more than two method calls on a single line, as it easily gets unreadable.

    Multi-Input Methods

    • Some methods take multiple input values. In Objective-C, a method name can be split up into several segments. In the header, a multi-input method looks like this:
    - (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile; 
    • You call the method like this:
    BOOL result = [myData writeToFile:@"/tmp/log.txt" atomically:NO]; 

    Accessors

    • All instance variables are private in Objective-C by default, so you should use accessors to get and set values in most cases. There are two syntaxes. This is the traditional 1.x syntax:
    [photo setCaption:@"Day at the Beach"];
    output = [photo caption]; 
    • The code on the second line is not reading the instance variable directly. It's actually calling a method named caption. In most cases, you don't add the "get" prefix to getters in Objective-C.

    Accessors Continued...

    • The dot syntax for getters and setters is new in Objective-C 2.0:
    photo.caption = @"Day at the Beach";
    output = photo.caption; 
    • You can use either style, but choose only one for each project. The dot syntax should only be used setters and getters, not for general purpose methods.


    Foundation Data Structures

    NSNumber

    • NSNumber is a generic container for numeric types 
      •  BOOL, char, short, int, long, float, and double
    • It lets you take one of the primitive types discussed earlier and interact with it in an object-oriented fashion. 
      • This is called boxing, and it's an essential tool for integrating Objective-C with C and C++ libraries.

    NSNumber Continued...

    • NSNumber provides several convenient methods to convert to and from primitive values. For example, you can store an integer in NSNumber with the following:
    int someInteger = -27;
    NSNumber *someNumber = [NSNumber numberWithInt:someInteger];
    • The recorded value can be accessed with the corresponding accessor method:
     NSLog(@"The stored number is: %i", [someNumber intValue]);
    
    //Accessors for other primitives follow the same pattern: floatValue, doubleValue, boolValue, etc.

    NSDecimalNumber

    • The NSDecimalNumber class is Objective-C's fixed-point class. 
    • It can represent much more precise numbers than float or double, and is thus the preferred way to represent money or other precision-sensitive data. 
    NSDecimalNumber *subtotal = [NSDecimalNumber decimalNumberWithString:@"10.99"];
    

    NSDecimalNumber Continued...

    • Since NSDecimalNumber uses more precise arithmetic algorithms than floating-point numbers, you can't use the standard +, -, *, or / operators. Instead, NSDecimalNumber provides its own methods for all of these operations:
    - decimalNumberByAdding:(NSDecimalNumber *)aNumber
    - decimalNumberBySubtracting:(NSDecimalNumber *)aNumber
    - decimalNumberByMultiplyingBy:(NSDecimalNumber *)aNumber
    - decimalNumberByDividingBy:(NSDecimalNumber *)aNumber
    

    NSString

    • At heart, NSString is a glorified C array of integers representing characters. Its two most basic methods are:
    • - (NSUInteger)length // Return the number of characters in the string.
      - (unichar)characterAtIndex:(NSUInteger)theIndex // Return the character at theIndex.
    • These two methods make it possible to iterate through individual characters in a string. For example:
    NSString *quote = @"Open the pod bay doors, HAL.";
    	
    for (int i=0; i<[quote length]; i++) {
        NSLog(@"%c", [quote characterAtIndex:i]);
    }
    
    // Prints out "Open the pod bay doors, HAL." into the console one letter at a time.

    NSString Continued...

    • The real power of NSString comes in its higher-level functionality.  Some of the most common methods are described in the following list...
    • + (id)stringWithFormat:(NSString *)format ... - Create a string using the same placeholder format as NSLog().
      - (NSString *)stringByAppendingString:(NSString *)aString - Append a string to the receiving object.
      - (NSString *)stringByAppendingFormat:(NSString *)format ... - Append a string using the same placeholder format as NSLog().
      - (NSString *)lowercaseString - Return the lowercase representation of the receiving string.
      - (NSString *)substringWithRange:(NSRange)aRange - Return a substring residing in aRange.
      - (NSRange)rangeOfString:(NSString *)aString - Search for aString in the receiving string and return the location and length of the result as an NSRange.
      - (NSString *)stringByReplacingOccurancesOfString:(NSString *)target withString:(NSString *)replacement - Replace all occurrences of target with replacement.

    NSMutableString

    •  A mutable string is one that lets you change individual characters without generating an entirely new string.
      •  If you're making many small changes to a string, a mutable string is more efficient, since it changes the characters in place. 
      • An immutable string, on the other hand, would have to allocate a new string for each change.
    • NSMutableString is implemented as a subclass of NSString, so you have access to all of the NSString methods, along with the addition of a few new methods for manipulating the character array in place...

    NSMutableString Continued...

    - (void)appendString:(NSString *)aString - Append aString to the end of the receiving string.
    
    - (void)appendFormat:(NSString *)format ... - Append a string using the same placeholder format as NSLog().
    
    	
    - (void)insertString:(NSString *)aString atIndex (NSUInteger)anIndex - Insert a string into the specified index.
    
    - (void)deleteCharactersInRange:(NSRange)aRange - Remove characters from the receiving string.
    
    - (void)replaceCharactersInRange:(NSRange)aRange withString:(NSString *)aString - Replace the characters in aRange with aString. 

    • Note that these methods all have void return types, whereas the corresponding NSString methods return NSString objects. This is indicative of the behavior of mutable strings: nothing needs to be returned, because the characters are manipulated in place.

    NSArray

    • Arrays are ordered collections of objects that let you maintain and sort lists of data. 
    • Like NSString, NSArray is immutable, so its contents cannot be changed without requesting an entirely new array. 
    • The most important NSArray methods are shown in the following list.

    + (id)arrayWithObjects:(id)firstObject, ... - Create a new array by passing in a list of objects.
    - (NSUInteger)count - Return the number of elements in the array.
    - (id)objectAtIndex:(NSUInteger)anIndex - Return the element in the array at index anIndex.
    - (BOOL)containsObject:(id)anObject - Return whether or not anObject is an element of the array.
    - (NSUInteger)indexOfObject:(id)anObject - Return the index of the first occurrence of anObject in the array. If the object is not in the array, return the NSNotFound constant.
    - (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))compareFunction context:(void *)context - Sort an array by comparing objects with a user-defined function.

    NSMutableArray

    • NSMutableArray is the mutable counterpart of NSArray. 
    • It's possible to change items after the array has been allocated and to extend or shrink the array by an arbitrary number of elements. 
    • While not as efficient as NSArray, the ability to incrementally add or remove items makes NSMutableArray a common data structure in Objective-C applications. 

    NSMutableArray Continued...

    • Provides  a few extra methods in addition to NSArray for manipulating contents:
    • - (void)addObject:(id)anObject - Add the given object to the end of the existing array.
      
      - (void)insertObject:(id)anObject atIndex:(NSUInteger)anIndex - Insert the given object into the specified index.
      
      - (void)removeObjectAtIndex:(NSUInteger)anIndex - Remove the object at the specified index.
      
      - (void)replaceObjectAtIndex:(NSUInteger)anIndex withObject:(id)anObject     Overwrite the object at anIndex with anObject.
      
      - (void)exchangeObjectAtIndex:(NSUInteger)index1 withObjectAtIndex:(NSUInteger)index2 - Swap the locations of two objects in the array.
      

    The id Data Type

    • Not technically a part of the Foundation framework.
    • Meant to be a generic object data type. 
      • It can hold a pointer to any Objective-C object, regardless of its class. 
      • This makes it possible to store different kinds of objects in a single variable, opening the door to dynamic programming. 
        • For example, id lets you store an NSNumber, an NSDecimalNumber, or an NSString in the same variable.

    id Continued

    id mysteryObject = [NSNumber numberWithInt:5];
    NSLog(@"%@", mysteryObject);
     
    mysteryObject = [NSDecimalNumber decimalNumberWithString:@"5.1"];
    NSLog(@"%@", mysteryObject);
     
    mysteryObject = @"5.2";
    NSLog(@"%@", mysteryObject);

    • Since an id variable doesn't check what kind of object it contains, it's the programmer's responsibility to makes sure he or she doesn't call methods or access properties that aren't defined on the object. 
    • In other words, don't try to call stringValue when the variable contains an NSString instance.

    The Class Data Type

    • Objective-C classes are actually objects themselves, and they can be stored in variables using the Class type. 
    • You can get the class object associated with a particular class by sending it the class message. 

    Class Continued...

    • The following example shows how to retrieve a class object, store it in a Class variable, and use it to figure out which kind of object is stored in an id variable:
    Class targetClass = [NSString class];
    id mysteryObject = [NSNumber numberWithInt:5];NSLog(@"%i", [mysteryObject isKindOfClass:targetClass]);
    mysteryObject = [NSDecimalNumber decimalNumberWithString:@"5.1"];NSLog(@"%i", [mysteryObject isKindOfClass:targetClass]);
    mysteryObject = @"5.2";NSLog(@"%i", [mysteryObject isKindOfClass:targetClass]);

    The Class data type brings the same dynamic capabilities to classes that id brings to objects.




    Let Code!


    iOS100 - iOS Platform Development Introduction - Objective-C Basics Flow Control, Data Types & Foundation Structures

    By Alex Rodriguez

    iOS100 - iOS Platform Development Introduction - Objective-C Basics Flow Control, Data Types & Foundation Structures

    Learn more about flow control, data types & foundation structures in Objective-C

    • 2,418