Getting Started
     Day 1
Where we’re headed:
‣Hello World
‣Xcode
‣About Objective-C
‣Syntax
‣Types
‣Operators
‣Classes & Objects Part 1
‣Fraction Calculator App
The Fraction Calculator
‣ Work with basic data
  types

‣ Work with simple
  objects and a simple
  object model

‣ Basic MVC architecture
‣ Build a basic UI with
  interface builder
Hello World
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
   NSAutoreleasePool * pool =
                   [[NSAutoreleasePool alloc] init];

    // insert code here...
    NSLog(@"Hello, World!");
    [pool drain];
    return 0;
}




    Hello World Example
Brief Xcode Tour
Starting a new project
The main window
The Console
Debug Window
Objective-C Basics
What is Objective-C
‣ An orthogonal superset over C
 ‣ Orthogonal = doesn’t override any C
      functionality (almost)
‣   Object oriented
‣   Syntax a mix of SmallTalk and C
‣   Can be statically or dynamically typed
Objective-C Filetypes
‣   .xcodeproj - Your project bundle
‣   .h - header file
‣   .c - a C source file
‣   .m - an Objective-C source file
‣   .plist - a property list file
Syntax
‣ All statements end with a semi-colon
‣ Blocks (lower case ‘b’) are denoted by curly braces
‣ Comments:
  ‣ // in-line comment
  ‣ /* . . . . */ block comment
  ‣ # pre-processor directive
Syntax
 Function Definition
 int cube (int num)
 {
 
 return num * num;
 }



 Function Calls
 cube (10);


 Declaring Variables
 int value = 10;
C Types
‣ Basic Types
  ‣ Int - an integer
  ‣ Float - decimal number
  ‣ Double - double precision decimal number
  ‣ Char - a single ASCII character (1 byte)
  ‣ Void - nothing (a variable cannot be declared void)
‣ Variations
  ‣ Signed / Unsigned (for ints)
  ‣ Long, long long (32 or 64 bits)
  ‣ Short (16 bits)
‣ Casting
  ‣ ( type ) variable
Objective-C Additions
‣ BOOL - boolean
  ‣ YES or NO
‣ id - pointer type for an objective-c object
‣ nil - the null value for objective-c
Esoteric Types
 Struct
 struct CGPoint {
   CGFloat x;
   CGFloat y;
 };

 Union
 union aNumber {
 
 int i;
 
 float f;
 }

 Enum
 enum CGRectEdge {
 
 CGRectMinXEdge,
 
 CGRectMinYEdge,
 
 CGRectMaxXEdge,
 
 CGRectMaxYEdge
 };
Esoteric Types
 Basic Typedef
 typedef long NSInteger;



 With a struct or enum
 typedef struct {
   CGFloat x;
   CGFloat y;
 } CGPoint;
Operators
‣ Arithmetic
  ‣ + addition
  ‣ - subtraction
  ‣ * multiplication
  ‣ / division
  ‣ % modulus
‣ Unary
  ‣ ++ increment
  ‣ -- decrement
Operators
‣ Assignment
  ‣ = simple assignment
  ‣ += add to
  ‣ -= subtract from
  ‣ *= multiply by
  ‣ /= divide by
Operators
‣ Logical
  ‣ == - equal to
  ‣ != - not equal to
  ‣ <, > - less than, greater than
  ‣ <=, >= - less than or equal, greater than or equal
  ‣ && - logical AND
  ‣ || - logical OR
‣ Pointers and References
  ‣ * - dereference
  ‣ & - reference (address of)
OO Syntax
‣ The ‘@’ symbol
  ‣ Used to create NSStrings
  ‣ Used as a prefix to obj-c keywords
‣ Calling Object Methods

 [[NSAutoreleasePool alloc] init];



 [NSDictionary dictionaryWithObject:@"foo" forKey:@"bar"];
Loops
 For loop
 for (int i = 0; i < 100; i++)
 {
 
 /* statements */
 }

 While loop
 while (condition)
 {
 
 /* statements */
 }

 Do ... While loop
 do {
 
 /* statements */
 } while (condition);
Branching
 If ... else if ... else
 if (condition)
 {
 
 /* statements */
 }
 else if (anotherCondition)
 {
 
 /* statements */
 }
 else
 {
 
 /* statements */
 }
Branching
 Switch
 switch (expression)
 {
 
 case aConstant:
 
 
    /* statements */
 
 
    break;
 
 case anotherConst:
 
 
    /* statements */
 
 
    break;
 
 default:
 
 
    /* statements */
 
 
    break;
 }

 Ternary Operator
 int value = condition ? 10 : 20;
Classes and Objects
What Defines an Object
‣Actions
‣Properties
A Car Object
‣ Properties
  ‣ Make
  ‣ Model
  ‣ Year
  ‣ Color
‣ Actions
  ‣ Accelerate
  ‣ Lock
  ‣ Steer
Objective-c Objects
‣ Data and Interface



   Data      Interface   Message



     ‣Messages are sent to Objects
     ‣Objects may respond to messages
Messaging
‣ Messages are sent to objects
  ‣ Different than calling a method
  ‣ Messages are referred to as selectors
  ‣ The object knows its type and will respond
        accordingly.
    ‣ All selectors are “virtual”
‣   Objects may respond to messages
‣   If the selector doesn’t exist (is unrecognized) an
    exception is typically thrown.
Sample Class Interface
@interface MyClass : NSObject
{

 int value

 id someData

 NSString *name
}

- (id)initWithName:(NSString *)name;
+ (MyClass *)createWithName:(NSString *)name;

@end
Sample Class Implementation
@implementation MyClass

-   (id)initWithName:(NSString *)aname
{

   self = [super init];

   if (self)

   {

   
     name = [aname copy];

   }

   return self
}

+ (MyClass *)createWithName:(NSString *)name
{

 return [[[self alloc] initWithName:name] autorelease];
}

@end
Named Properties
 Named Property Declaration
 @property (nonatomic, retain) NSString *name;
 @property (nonatomic, assign) int value;




 Interface Implementation
 @synthesize name, value;



At compile time, the @synthesize produces getters
and setters.
Sample Class Interface
@interface MyClass : NSObject
{

 int value

 id someData

 NSString *name
}

- (id)initWithName:(NSString *)name;
+ (MyClass *)createWithName:(NSString *)aname;

@property (nonatomic, retain) NSString *name;
@property (nonatomic, assign) int value;

@end
Sample Class Implementation
@implementation MyClass

@synthesize name, value;

-   (id)initWithName:(NSString *)aname
{

   self = [super init];

   if (self)

   {

   
     name = [aname copy];

   }

   return self
}

+ (MyClass *)createWithName:(NSString *)name
{

 return [[[self alloc] initWithName:name] autorelease];
}
Fraction Calculator
Project Overview
‣ Fraction Class
‣ Calculator Class
‣ View Controller
‣ UI File (.xib)
Architecture

             View
 Xib file                Calculator
           Controller
                         Fraction


 View      Controller   “Model”
The Fraction Class
‣ Properties
  ‣ Numerator
  ‣ Denominator
‣ Actions
  ‣ Create
  ‣ Set properties
  ‣ Add, Subtract fractions
  ‣ Multiply, Divide fractions
  ‣ Reduce
Fraction Interface
     @interface Fraction : NSObject
{

   int numerator;

   int denominator;
}

-   (id)initWithNumerator:(int)num denominator:(int)denom;
-   (double)asDecimal;
-   (Fraction *)add:(Fraction *)fraction;
-   (Fraction *)subtract:(Fraction *)fraction;
-   (Fraction *)multiply:(Fraction *)fraction;
-   (Fraction *)divide:(Fraction *)fraction;
 
 
 
 

    
    
 
 
 
-   (void)reduce;

@property (nonatomic, assign) int numerator;
@property (nonatomic, assign) int denominator;

@end
Fraction Implementation
   #import "Fraction.h"


@implementation Fraction

@synthesize numerator;
@synthesize denominator;
Fraction Implementation
    - (id)initWithNumerator:(int)num denominator:(int)denom
{

   if (self = [super init])

   {

   
     numerator = num;

   
     denominator = denom != 0 ? denom : 1;

   }


   return self;
}

- (NSString *)description
{

 return [NSString stringWithFormat:@"Fraction: %d/%d", numerator,
denominator];
}
Fraction Implementation
    - (void)setDenominator:(int)denom
{

   if (denom != 0)

   {

   
    denominator = denom;

   }

   else

   {

   
    denominator = 1;

   }

}

- (double)asDecimal
{

 return (double)numerator / denominator;
}
Fraction Implementation
    // page 144
- (Fraction *)add:(Fraction *)fraction
{

 int resultNum, resultDenom;

 resultNum = numerator * fraction.denominator
 + denominator * fraction.numerator;


 resultDenom = denominator * fraction.denominator;


 Fraction *result = [[Fraction alloc] initWithNumerator:resultNum
denominator:resultDenom];


   [result reduce];


   return result;
}
Fraction Implementation
  - (Fraction *)subtract:(Fraction *)fraction
{

 Fraction *tmp = [[Fraction alloc] initWithNumerator:
-fraction.numerator

 
     
 
 
 
 
 
 
 
 
 denominator:fraction.denominator];

 Fraction *result = [self add:tmp];

 [tmp release];

 return result;
}
Fraction Implementation
    - (Fraction *)multiply:(Fraction *)fraction
{

   int resultNum, resultDenom;

   resultNum = numerator * fraction.numerator;

   resultDenom = denominator * fraction.denominator;


   Fraction *result = [[Fraction alloc] initWithNumerator:resultNum

   
   denominator:resultDenom];

   [result reduce];


   return result;

   
   
 
 
 
}
Fraction Implementation
    - (Fraction *)divide:(Fraction *)fraction
{

   Fraction *tmp = [[Fraction alloc] initWithNumerator:fraction.denominator

   
   denominator:fraction.numerator];


   Fraction *result = [self multiply:tmp];

   [tmp release];

   return result;
}
Fraction Implementation
    // page 146
- (void)reduce
{

 int tmpNum = numerator;

 int tmpDen = denominator;

 int temp = 0;


 while (tmpDen != 0)

 {

 
     temp = tmpNum % tmpDen;

 
     tmpNum = tmpDen;

 
     tmpDen = temp;

 }


 numerator /= tmpNum;

 denominator /= tmpNum;
}
Calculator Class
‣ Properties
  ‣ An operation to perform
  ‣ 2 operands
  ‣ A result of an operation
‣ Actions
  ‣ Set properties
  ‣ Perform an operation
Calculator Interface
    #import "Fraction.h"

typedef enum
{

 CalcOpAdd,

 CalcOpMul,

 CalcOpDiv,

 CalcOpSub
} CalculatorOperation;

@interface Calculator : NSObject
{

 Fraction *operand1;

 Fraction *operand2;

 Fraction *result;
}

- (void)performOperation:(CalculatorOperation)op;
- (void)reset;

@property (nonatomic, retain) Fraction *operand1, *operand2;
@property (nonatomic, readonly) Fraction *result;

@end
Calculator Implementation
     #import "Calculator.h"

@implementation Calculator

@synthesize operand1, operand2, result;

-   (void)dealloc
{

   [operand1 release];

   [operand2 release];

   [result release];

   [super dealloc];
}
Calculator Implementation
    - (void)performOperation:(CalculatorOperation)op
{

   switch (op) {

   
   case CalcOpAdd:

   
   
 result = [operand1   add:operand2];

   
   
 break;

   
   case CalcOpSub:

   
   
 result = [operand1   subtract:operand2];

   
   
 break;

   
   case CalcOpMul:

   
   
 result = [operand1   multiply:operand2];

   
   
 break;

   
   case CalcOpDiv:

   
   
 result = [operand1   divide:operand2];

   
   
 break;

   
   default:

   
   
 break;

   }
}
Calculator Implementation
    - (void)reset
{

   self.operand1 = nil;

   self.operand2 = nil;

   [result release];

   result = nil;
}

@end
View Controller
‣ Subclass of UIViewController
‣ Properties
  ‣ View
‣ Actions
  ‣ Respond to UI Events
  ‣ Manipulate UI Elements
‣ As a subclass of UIViewController, many functions
  are provided already.
VC Interface
    @interface FractionCalculatorViewController : UIViewController
{

   UILabel *display;

   NSMutableString *displayString;

   Calculator *calculator;

   CalculatorOperation op;


   BOOL workingNumerator;

   BOOL workingFirstNumber;
}
VC Interface
      - (IBAction)numberButtonTap:(UIButton *)sender;
-   (IBAction)opButtonTap:(UIButton *)sender;
-   (IBAction)overButtonTap:(UIButton *)sender;
-   (IBAction)clearButtonTap:(UIButton *)sender;
-   (IBAction)equalsButtonTap:(UIButton *)sender;

@property (nonatomic, retain) IBOutlet UILabel *display;
@property (nonatomic, retain) NSMutableString *displayString;
VC Interface
     typedef enum {

    OperatorButtonTagAdd = 10,

    OperatorButtonTagSub = 11,

    OperatorButtonTagMul = 12,

    OperatorButtonTagDiv = 13
}   OperatorButtonTag;
VC Implementation
     - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]))

     {

     
     calculator = [[Calculator alloc] init];

     
     displayString = [[NSMutableString alloc] init];

     
     workingNumerator = YES;

     
     workingFirstNumber = YES;
    }
    return self;
}

- (void)dealloc
{

 [display release];

 [displayString release];

 [calculator release];
   [super dealloc];
}
VC Implementation
     - (IBAction)numberButtonTap:(UIButton *)sender
{

   [displayString appendString:[NSString stringWithFormat:@"%d", [sender tag]]];


   Fraction *f;


   if (workingFirstNumber)

   {

   
     if (calculator.operand1 == nil)

   
     {

   
     
     calculator.operand1 = [[Fraction alloc] init];

   
     }

   

   
     f = calculator.operand1;

   }

   else

   {

   
     if (calculator.operand2 == nil)

   
     {

   
     
     calculator.operand2 = [[Fraction alloc] init];

   
   
   

   
     }

   

   
     f = calculator.operand2;

   }
VC Implementation
        
   if (workingNumerator)

   {

   
       f.numerator *= 10;

   
       f.numerator += [sender tag];


   }

   else

   {

   
    f.denominator *= 10;

   
    f.denominator += [sender tag];

   }


   [display setText:displayString];
}
VC Implementation
     - (IBAction)opButtonTap:(UIButton *)sender
{

   switch ([sender tag])

   {

   
     case OperatorButtonTagAdd:

   
     
    op = CalcOpAdd;

   
     
    [displayString appendString:[NSString   stringWithFormat:@" + "]];

   
     
    break;

   
     case OperatorButtonTagSub:

   
     
    op = CalcOpSub;

   
     
    [displayString appendString:[NSString   stringWithFormat:@" - "]];

   
     
    break;

   
     case OperatorButtonTagMul:

   
     
    op = CalcOpMul;

   
     
    [displayString appendString:[NSString   stringWithFormat:@" x "]];

   
     
    break;

   
     case OperatorButtonTagDiv:

   
     
    op = CalcOpDiv;

   
     
    [displayString appendString:[NSString   stringWithFormat:@" ÷ "]];

   
     
    break;

   
     default:

   
     
    break;


   }

   workingFirstNumber = NO;

   workingNumerator = YES;

   [display setText:displayString];
}
VC Implementation
      - (IBAction)clearButtonTap:(UIButton *)sender
{

    workingFirstNumber = YES;

    workingNumerator = YES;


    calculator.operand1 = nil;

    calculator.operand2 = nil;


    [displayString setString:@""];

    [display setText:displayString];
}
-   (IBAction)overButtonTap:(UIButton *)sender
{

    [displayString appendString:@" / "];

    [display setText:displayString];

    workingNumerator = NO;
}
VC Implementation
    - (IBAction)equalsButtonTap:(UIButton *)sender
{

 NSLog(@"%@ %@", calculator.operand1, calculator.operand2);

 [calculator performOperation:op];

 [displayString setString:[NSString stringWithFormat:@"%d / %d", calculator.result.numerator,
calculator.result.denominator]];

 [display setText:displayString];
}

- (void)dealloc
{

 [display release];

 [displayString release];

 [calculator release];
   [super dealloc];
}
UIApplication Delegate
‣ Handles application after initial load.
‣ Houses the view controller
Application Delegate
    - (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Override point for customization after application launch.


   mainViewController = [[FractionCalculatorViewController alloc]

   
   
   
  
    
    initWithNibName:@"FractionCalculatorViewController"

   
   
   
  
    
    bundle:nil];


   [window addSubview:mainViewController.view];

    [window makeKeyAndVisible];

    return YES;
}
Creating the fraction UI
UI Files are xib files
Object Properties   Object Library

Day 1

  • 1.
  • 2.
    Where we’re headed: ‣HelloWorld ‣Xcode ‣About Objective-C ‣Syntax ‣Types ‣Operators ‣Classes & Objects Part 1 ‣Fraction Calculator App
  • 3.
    The Fraction Calculator ‣Work with basic data types ‣ Work with simple objects and a simple object model ‣ Basic MVC architecture ‣ Build a basic UI with interface builder
  • 4.
  • 5.
    #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // insert code here... NSLog(@"Hello, World!"); [pool drain]; return 0; } Hello World Example
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
    What is Objective-C ‣An orthogonal superset over C ‣ Orthogonal = doesn’t override any C functionality (almost) ‣ Object oriented ‣ Syntax a mix of SmallTalk and C ‣ Can be statically or dynamically typed
  • 13.
    Objective-C Filetypes ‣ .xcodeproj - Your project bundle ‣ .h - header file ‣ .c - a C source file ‣ .m - an Objective-C source file ‣ .plist - a property list file
  • 14.
    Syntax ‣ All statementsend with a semi-colon ‣ Blocks (lower case ‘b’) are denoted by curly braces ‣ Comments: ‣ // in-line comment ‣ /* . . . . */ block comment ‣ # pre-processor directive
  • 15.
    Syntax Function Definition int cube (int num) { return num * num; } Function Calls cube (10); Declaring Variables int value = 10;
  • 16.
    C Types ‣ BasicTypes ‣ Int - an integer ‣ Float - decimal number ‣ Double - double precision decimal number ‣ Char - a single ASCII character (1 byte) ‣ Void - nothing (a variable cannot be declared void) ‣ Variations ‣ Signed / Unsigned (for ints) ‣ Long, long long (32 or 64 bits) ‣ Short (16 bits) ‣ Casting ‣ ( type ) variable
  • 17.
    Objective-C Additions ‣ BOOL- boolean ‣ YES or NO ‣ id - pointer type for an objective-c object ‣ nil - the null value for objective-c
  • 18.
    Esoteric Types Struct struct CGPoint { CGFloat x; CGFloat y; }; Union union aNumber { int i; float f; } Enum enum CGRectEdge { CGRectMinXEdge, CGRectMinYEdge, CGRectMaxXEdge, CGRectMaxYEdge };
  • 19.
    Esoteric Types BasicTypedef typedef long NSInteger; With a struct or enum typedef struct { CGFloat x; CGFloat y; } CGPoint;
  • 20.
    Operators ‣ Arithmetic ‣ + addition ‣ - subtraction ‣ * multiplication ‣ / division ‣ % modulus ‣ Unary ‣ ++ increment ‣ -- decrement
  • 21.
    Operators ‣ Assignment ‣ = simple assignment ‣ += add to ‣ -= subtract from ‣ *= multiply by ‣ /= divide by
  • 22.
    Operators ‣ Logical ‣ == - equal to ‣ != - not equal to ‣ <, > - less than, greater than ‣ <=, >= - less than or equal, greater than or equal ‣ && - logical AND ‣ || - logical OR ‣ Pointers and References ‣ * - dereference ‣ & - reference (address of)
  • 23.
    OO Syntax ‣ The‘@’ symbol ‣ Used to create NSStrings ‣ Used as a prefix to obj-c keywords ‣ Calling Object Methods [[NSAutoreleasePool alloc] init]; [NSDictionary dictionaryWithObject:@"foo" forKey:@"bar"];
  • 24.
    Loops For loop for (int i = 0; i < 100; i++) { /* statements */ } While loop while (condition) { /* statements */ } Do ... While loop do { /* statements */ } while (condition);
  • 25.
    Branching If ...else if ... else if (condition) { /* statements */ } else if (anotherCondition) { /* statements */ } else { /* statements */ }
  • 26.
    Branching Switch switch(expression) { case aConstant: /* statements */ break; case anotherConst: /* statements */ break; default: /* statements */ break; } Ternary Operator int value = condition ? 10 : 20;
  • 27.
  • 28.
    What Defines anObject ‣Actions ‣Properties
  • 29.
    A Car Object ‣Properties ‣ Make ‣ Model ‣ Year ‣ Color ‣ Actions ‣ Accelerate ‣ Lock ‣ Steer
  • 30.
    Objective-c Objects ‣ Dataand Interface Data Interface Message ‣Messages are sent to Objects ‣Objects may respond to messages
  • 31.
    Messaging ‣ Messages aresent to objects ‣ Different than calling a method ‣ Messages are referred to as selectors ‣ The object knows its type and will respond accordingly. ‣ All selectors are “virtual” ‣ Objects may respond to messages ‣ If the selector doesn’t exist (is unrecognized) an exception is typically thrown.
  • 32.
    Sample Class Interface @interfaceMyClass : NSObject { int value id someData NSString *name } - (id)initWithName:(NSString *)name; + (MyClass *)createWithName:(NSString *)name; @end
  • 33.
    Sample Class Implementation @implementationMyClass - (id)initWithName:(NSString *)aname { self = [super init]; if (self) { name = [aname copy]; } return self } + (MyClass *)createWithName:(NSString *)name { return [[[self alloc] initWithName:name] autorelease]; } @end
  • 34.
    Named Properties NamedProperty Declaration @property (nonatomic, retain) NSString *name; @property (nonatomic, assign) int value; Interface Implementation @synthesize name, value; At compile time, the @synthesize produces getters and setters.
  • 35.
    Sample Class Interface @interfaceMyClass : NSObject { int value id someData NSString *name } - (id)initWithName:(NSString *)name; + (MyClass *)createWithName:(NSString *)aname; @property (nonatomic, retain) NSString *name; @property (nonatomic, assign) int value; @end
  • 36.
    Sample Class Implementation @implementationMyClass @synthesize name, value; - (id)initWithName:(NSString *)aname { self = [super init]; if (self) { name = [aname copy]; } return self } + (MyClass *)createWithName:(NSString *)name { return [[[self alloc] initWithName:name] autorelease]; }
  • 37.
  • 38.
    Project Overview ‣ FractionClass ‣ Calculator Class ‣ View Controller ‣ UI File (.xib)
  • 39.
    Architecture View Xib file Calculator Controller Fraction View Controller “Model”
  • 40.
    The Fraction Class ‣Properties ‣ Numerator ‣ Denominator ‣ Actions ‣ Create ‣ Set properties ‣ Add, Subtract fractions ‣ Multiply, Divide fractions ‣ Reduce
  • 41.
    Fraction Interface @interface Fraction : NSObject { int numerator; int denominator; } - (id)initWithNumerator:(int)num denominator:(int)denom; - (double)asDecimal; - (Fraction *)add:(Fraction *)fraction; - (Fraction *)subtract:(Fraction *)fraction; - (Fraction *)multiply:(Fraction *)fraction; - (Fraction *)divide:(Fraction *)fraction; - (void)reduce; @property (nonatomic, assign) int numerator; @property (nonatomic, assign) int denominator; @end
  • 42.
    Fraction Implementation #import "Fraction.h" @implementation Fraction @synthesize numerator; @synthesize denominator;
  • 43.
    Fraction Implementation - (id)initWithNumerator:(int)num denominator:(int)denom { if (self = [super init]) { numerator = num; denominator = denom != 0 ? denom : 1; } return self; } - (NSString *)description { return [NSString stringWithFormat:@"Fraction: %d/%d", numerator, denominator]; }
  • 44.
    Fraction Implementation - (void)setDenominator:(int)denom { if (denom != 0) { denominator = denom; } else { denominator = 1; } } - (double)asDecimal { return (double)numerator / denominator; }
  • 45.
    Fraction Implementation // page 144 - (Fraction *)add:(Fraction *)fraction { int resultNum, resultDenom; resultNum = numerator * fraction.denominator + denominator * fraction.numerator; resultDenom = denominator * fraction.denominator; Fraction *result = [[Fraction alloc] initWithNumerator:resultNum denominator:resultDenom]; [result reduce]; return result; }
  • 46.
    Fraction Implementation - (Fraction *)subtract:(Fraction *)fraction { Fraction *tmp = [[Fraction alloc] initWithNumerator: -fraction.numerator denominator:fraction.denominator]; Fraction *result = [self add:tmp]; [tmp release]; return result; }
  • 47.
    Fraction Implementation - (Fraction *)multiply:(Fraction *)fraction { int resultNum, resultDenom; resultNum = numerator * fraction.numerator; resultDenom = denominator * fraction.denominator; Fraction *result = [[Fraction alloc] initWithNumerator:resultNum denominator:resultDenom]; [result reduce]; return result; }
  • 48.
    Fraction Implementation - (Fraction *)divide:(Fraction *)fraction { Fraction *tmp = [[Fraction alloc] initWithNumerator:fraction.denominator denominator:fraction.numerator]; Fraction *result = [self multiply:tmp]; [tmp release]; return result; }
  • 49.
    Fraction Implementation // page 146 - (void)reduce { int tmpNum = numerator; int tmpDen = denominator; int temp = 0; while (tmpDen != 0) { temp = tmpNum % tmpDen; tmpNum = tmpDen; tmpDen = temp; } numerator /= tmpNum; denominator /= tmpNum; }
  • 50.
    Calculator Class ‣ Properties ‣ An operation to perform ‣ 2 operands ‣ A result of an operation ‣ Actions ‣ Set properties ‣ Perform an operation
  • 51.
    Calculator Interface #import "Fraction.h" typedef enum { CalcOpAdd, CalcOpMul, CalcOpDiv, CalcOpSub } CalculatorOperation; @interface Calculator : NSObject { Fraction *operand1; Fraction *operand2; Fraction *result; } - (void)performOperation:(CalculatorOperation)op; - (void)reset; @property (nonatomic, retain) Fraction *operand1, *operand2; @property (nonatomic, readonly) Fraction *result; @end
  • 52.
    Calculator Implementation #import "Calculator.h" @implementation Calculator @synthesize operand1, operand2, result; - (void)dealloc { [operand1 release]; [operand2 release]; [result release]; [super dealloc]; }
  • 53.
    Calculator Implementation - (void)performOperation:(CalculatorOperation)op { switch (op) { case CalcOpAdd: result = [operand1 add:operand2]; break; case CalcOpSub: result = [operand1 subtract:operand2]; break; case CalcOpMul: result = [operand1 multiply:operand2]; break; case CalcOpDiv: result = [operand1 divide:operand2]; break; default: break; } }
  • 54.
    Calculator Implementation - (void)reset { self.operand1 = nil; self.operand2 = nil; [result release]; result = nil; } @end
  • 55.
    View Controller ‣ Subclassof UIViewController ‣ Properties ‣ View ‣ Actions ‣ Respond to UI Events ‣ Manipulate UI Elements ‣ As a subclass of UIViewController, many functions are provided already.
  • 56.
    VC Interface @interface FractionCalculatorViewController : UIViewController { UILabel *display; NSMutableString *displayString; Calculator *calculator; CalculatorOperation op; BOOL workingNumerator; BOOL workingFirstNumber; }
  • 57.
    VC Interface - (IBAction)numberButtonTap:(UIButton *)sender; - (IBAction)opButtonTap:(UIButton *)sender; - (IBAction)overButtonTap:(UIButton *)sender; - (IBAction)clearButtonTap:(UIButton *)sender; - (IBAction)equalsButtonTap:(UIButton *)sender; @property (nonatomic, retain) IBOutlet UILabel *display; @property (nonatomic, retain) NSMutableString *displayString;
  • 58.
    VC Interface typedef enum { OperatorButtonTagAdd = 10, OperatorButtonTagSub = 11, OperatorButtonTagMul = 12, OperatorButtonTagDiv = 13 } OperatorButtonTag;
  • 59.
    VC Implementation - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) { calculator = [[Calculator alloc] init]; displayString = [[NSMutableString alloc] init]; workingNumerator = YES; workingFirstNumber = YES; } return self; } - (void)dealloc { [display release]; [displayString release]; [calculator release]; [super dealloc]; }
  • 60.
    VC Implementation - (IBAction)numberButtonTap:(UIButton *)sender { [displayString appendString:[NSString stringWithFormat:@"%d", [sender tag]]]; Fraction *f; if (workingFirstNumber) { if (calculator.operand1 == nil) { calculator.operand1 = [[Fraction alloc] init]; } f = calculator.operand1; } else { if (calculator.operand2 == nil) { calculator.operand2 = [[Fraction alloc] init]; } f = calculator.operand2; }
  • 61.
    VC Implementation if (workingNumerator) { f.numerator *= 10; f.numerator += [sender tag]; } else { f.denominator *= 10; f.denominator += [sender tag]; } [display setText:displayString]; }
  • 62.
    VC Implementation - (IBAction)opButtonTap:(UIButton *)sender { switch ([sender tag]) { case OperatorButtonTagAdd: op = CalcOpAdd; [displayString appendString:[NSString stringWithFormat:@" + "]]; break; case OperatorButtonTagSub: op = CalcOpSub; [displayString appendString:[NSString stringWithFormat:@" - "]]; break; case OperatorButtonTagMul: op = CalcOpMul; [displayString appendString:[NSString stringWithFormat:@" x "]]; break; case OperatorButtonTagDiv: op = CalcOpDiv; [displayString appendString:[NSString stringWithFormat:@" ÷ "]]; break; default: break; } workingFirstNumber = NO; workingNumerator = YES; [display setText:displayString]; }
  • 63.
    VC Implementation - (IBAction)clearButtonTap:(UIButton *)sender { workingFirstNumber = YES; workingNumerator = YES; calculator.operand1 = nil; calculator.operand2 = nil; [displayString setString:@""]; [display setText:displayString]; } - (IBAction)overButtonTap:(UIButton *)sender { [displayString appendString:@" / "]; [display setText:displayString]; workingNumerator = NO; }
  • 64.
    VC Implementation - (IBAction)equalsButtonTap:(UIButton *)sender { NSLog(@"%@ %@", calculator.operand1, calculator.operand2); [calculator performOperation:op]; [displayString setString:[NSString stringWithFormat:@"%d / %d", calculator.result.numerator, calculator.result.denominator]]; [display setText:displayString]; } - (void)dealloc { [display release]; [displayString release]; [calculator release]; [super dealloc]; }
  • 65.
    UIApplication Delegate ‣ Handlesapplication after initial load. ‣ Houses the view controller
  • 66.
    Application Delegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. mainViewController = [[FractionCalculatorViewController alloc] initWithNibName:@"FractionCalculatorViewController" bundle:nil]; [window addSubview:mainViewController.view]; [window makeKeyAndVisible]; return YES; }
  • 67.
  • 68.
    UI Files arexib files
  • 69.
    Object Properties Object Library