Chapter 19, Challenge solution


#1

This is my challenge solution. If you have questions or remarks, you can always tell me!

[code]//
// StockHolding.h
// Stocks
//
// Created by Maxime Defauw on 31/12/13.
// Copyright © 2013 Maxime Defauw. All rights reserved.
//

#import <Foundation/Foundation.h>
@class Portfolio;

@interface StockHolding : NSObject
{
float purchasePrice;
float currentSharePrice;
int numberOfShares;
}

@property float purchasePrice;
@property float currentSharePrice;
@property int numberOfShares;

  • (float)costInDollars;
  • (float)valueInDollars;

@end
[/code]

[code]//
// StockHolding.m
// Stocks
//
// Created by Maxime Defauw on 31/12/13.
// Copyright © 2013 Maxime Defauw. All rights reserved.
//

#import “StockHolding.h”
#import “Portfolio.h”

@implementation StockHolding

@synthesize purchasePrice, currentSharePrice, numberOfShares;

  • (float)costInDollars
    {
    return [self purchasePrice] * [self numberOfShares];
    }

  • (float)valueInDollars
    {
    return [self currentSharePrice] * [self numberOfShares];
    }

@end[/code]

[code]//
// ForeignStockHolding.h
// Stocks
//
// Created by Maxime Defauw on 7/01/14.
// Copyright © 2014 Maxime Defauw. All rights reserved.
//

#import “StockHolding.h”

@interface ForeignStockHolding : StockHolding
{
float conversionRate;
}

@property float conversionRate;

@end
[/code]

[code]//
// ForeignStockHolding.m
// Stocks
//
// Created by Maxime Defauw on 7/01/14.
// Copyright © 2014 Maxime Defauw. All rights reserved.
//

#import “ForeignStockHolding.h”

@implementation ForeignStockHolding

@synthesize conversionRate;

  • (float)costInDollars
    {
    float foreignCostInDollars = [super costInDollars];
    return foreignCostInDollars * conversionRate;
    }

  • (float)valueInDollars
    {
    float foreignValueInDollars = [super valueInDollars];
    return foreignValueInDollars * conversionRate;
    }

@end
[/code]

[code]//
// Portfolio.h
// Stocks
//
// Created by Maxime Defauw on 8/01/14.
// Copyright © 2014 Maxime Defauw. All rights reserved.
//

#import <Foundation/Foundation.h>
@class StockHolding;

@interface Portfolio : NSObject
{
NSMutableArray *portfolio;
}

@property (strong)NSMutableArray *portfolio;

  • (void)addStockToPortfolio:(StockHolding *)s;
  • (float)valueOfPortfolio;

@end
[/code]

[code]//
// Portfolio.m
// Stocks
//
// Created by Maxime Defauw on 8/01/14.
// Copyright © 2014 Maxime Defauw. All rights reserved.
//

#import “Portfolio.h”
#import “StockHolding.h”

@implementation Portfolio

@synthesize portfolio;

  • (void)addStockToPortfolio:(StockHolding *)s
    {
    if (!portfolio) {
    portfolio = [[NSMutableArray alloc]init];
    }
    [portfolio addObject:s];
    }

  • (float)valueOfPortfolio
    {
    float sum = 0;

    for (StockHolding *s in portfolio)
    {
    sum += [s valueInDollars];
    }
    return sum;
    }

@end[/code]

[code]//
// main.m
// Stocks
//
// Created by Maxime Defauw on 31/12/13.
// Copyright © 2013 Maxime Defauw. All rights reserved.
//

#import <Foundation/Foundation.h>
#import “ForeignStockHolding.h”
#import “Portfolio.h”

int main(int argc, const char * argv[])
{

@autoreleasepool {
    
    Portfolio *myPortfolio = [[Portfolio alloc]init];
    
    StockHolding *Apple = [[StockHolding alloc]init];
        [Apple setPurchasePrice:2.30];
        [Apple setCurrentSharePrice:4.50];
        [Apple setNumberOfShares:40];
        [myPortfolio addStockToPortfolio:Apple];
    
    StockHolding *Microsoft = [[StockHolding alloc]init];
        [Microsoft setPurchasePrice:12.19];
        [Microsoft setCurrentSharePrice:10.56];
        [Microsoft setNumberOfShares:90];
        [myPortfolio addStockToPortfolio:Microsoft];
    
    ForeignStockHolding *Android = [[ForeignStockHolding alloc]init];
        [Android setPurchasePrice:45.10];
        [Android setCurrentSharePrice:49.51];
        [Android setNumberOfShares:210];
        [Android setConversionRate:3.2];
        [myPortfolio addStockToPortfolio:Android];
    
    NSMutableArray *myStocks = [[NSMutableArray alloc]init];
        [myStocks addObject:Apple];
        [myStocks addObject:Microsoft];
        [myStocks addObject:Android];
   
    for (StockHolding *s in myStocks)
    {
        NSLog(@"Stock (%f, %f) has a value of %f", [s purchasePrice], [s currentSharePrice], [s valueInDollars]);
    }
    
    NSLog(@"At the moment, my portfolio has a value of %f", [myPortfolio valueOfPortfolio]);
    
}
return 0;

}[/code]

2014-01-08 20:57:23.469 Stocks[2129:303] Stock (2.300000, 4.500000) has a value of 180.000000 2014-01-08 20:57:23.470 Stocks[2129:303] Stock (12.190000, 10.560000) has a value of 950.400024 2014-01-08 20:57:23.471 Stocks[2129:303] Stock (45.099998, 49.509998) has a value of 33270.718750 2014-01-08 20:57:23.471 Stocks[2129:303] At the moment, my portfolio has a value of 34401.117188


#2

I am very new to objective c, but was thinking that the array should be declared in the Portfolio.m file so that the array would remain untouchable except through it’s public methods. Am I correct in understanding that if declared as shown in Portfolio.h that anything would have direct access to the array?

Thanks in advance for your answer.


#3

Yes, that’s a good design/implementation strategy - hide as much as possible.

Incidentally, in the following interface:

[quote][code]
// Portfolio.h

@class StockHolding;
@interface Portfolio : NSObject
{
NSMutableArray *portfolio;
}
@property (strong) NSMutableArray *portfolio;

  • (void)addStockToPortfolio:(StockHolding *)s;
  • (float)valueOfPortfolio;
    @end
    [/code][/quote]
    It is better to declare the property like this:
@property (readonly, copy) NSArray *portfolio;

This will ensure that portfolio array can be modified only through the interface provided.


#4

Thanks for the response. As I said am new and having a little trouble with the @properties and @synthesize.
First, what kind of setter and getter is automatically set up when the object is an array.
Second, is the underscore variable that is created by @synthesize just like a local variable that could be bypassed using the self.variable instead of _variable? (Hope that made sense)

Thanks


#5

If you mean a setter/getter for accessing the objects in the array, none.

[quote]Second, is the underscore variable that is created by @synthesize just like a local variable that could be bypassed using the self.variable instead of _variable? (Hope that made sense)
[/quote]
Yes. (But keep in mind that accessing through self.variable is not the same as accessing _variable directly.)


#6

So what does get set up when you use @properties and @synthesize with an array?


#7

Let’s pretend that we have this:

@interface Foo: NSObject

@property (readonly) NSArray *bars;

@end

The default implementation (the auto-synthesised version) of getBars would look something like this:

@implementation Foo
{
   NSArray *_bars;
}
...
- (NSArray *)getBars
{
   ...
   return _bars;
}
...
@end

It will simply return _bars even if the object was uninitialised.

However, if we were to write it ourselves, we would write it something like this:

@implementation Foo
{
   NSArray *_bars;
}
...
- (NSArray *)getBars
{
   ...
   if (!_bars) {
        _bars = [self configureBars];
   }
   return [_bars copy];
}
...
@end

The following resources provide more information:
Concepts in Objective-C Programming - developer.apple.com/library/mac … 0-CH5-SW65

Programming with Objective-C - developer.apple.com/library/mac … 10-CH1-SW1


#8

So one last question and I will move on. Since with an array, the automatic getters and setters neither alloc nor provide values to or from specific elements of the array, using properties is of little use? You will need to create your own get and set methods to have anything of value either occur or return?


#9

Yes.

Properties create the backing store for fundamental data types, but for other types, for example NSMutableArray, you need to create the backing store manually before you can do something useful through the property.


#10

hi guys, it’s nice to working on challenge and build it and seems “working” ;p

my solution :

main.m

[code]#import <Foundation/Foundation.h>
#import “Action.h”
#import “PorteFeuille.h”

int main(int argc, const char * argv[])
{

@autoreleasepool {
    
    Action *action1 = [[Action alloc] init];
    [action1 setPrixAchatAction:2.30];
    [action1 setPrixActuelAction:4.50];
    [action1 setNbActions:40];
    
    Action *action2 = [[Action alloc] init];
    [action2 setPrixAchatAction:12.19];
    [action2 setPrixActuelAction:10.56];
    [action2 setNbActions:90];
    
    Action *action3 = [[Action alloc] init];
    [action3 setPrixAchatAction:45.10];
    [action3 setPrixActuelAction:45.51];
    [action3 setNbActions:210];
    
    //on declare notre portefeuille
    PorteFeuille *mp = [[PorteFeuille alloc] init];
    
    //On ajoute au tableau PorteFeuille nos actions
    [mp AjouterAuPortefeuille:action1];
    [mp AjouterAuPortefeuille:action2];
    [mp AjouterAuPortefeuille:action3];
    
    NSMutableArray *mesActions = [[NSMutableArray alloc] initWithObjects:action1, action2, action3, nil];
    
    for (Action *d in mesActions) {
        NSLog(@"prix achat : %.2f, le prix actuel %.2f - le cout %.2f et la valeur %.2f", [d prixAchatAction], [d prixActuelAction], [d coutEnEuros], [d valeurEnEuros]);
    }
    
    NSLog(@"la valeur de notre portefeuille est %.2f", [mp valeurPortefeuille]);

}
return 0;

}
[/code]

PorteFeuille.h

[code]#import <Foundation/Foundation.h>
@class Action;

@interface PorteFeuille : NSObject {
NSMutableArray *monPortefeuille;
}

  • (void)AjouterAuPortefeuille:(Action *)p;
  • (float)valeurPortefeuille;

@end
[/code]

PorteFeuille.m

[code]#import “PorteFeuille.h”
#import “Action.h”

@implementation PorteFeuille

  • (void)AjouterAuPortefeuille:(Action *)p {

    if (!monPortefeuille) {
    monPortefeuille = [[NSMutableArray alloc] init];
    }
    [monPortefeuille addObject:p];
    }

  • (float)valeurPortefeuille {

    float somme = 0;
    for (Action *p in monPortefeuille) {
    somme += [p valeurEnEuros];
    }
    return somme;
    }
    @end
    [/code]

action.m et .h same that the previous challenge