Trouble with a Solution to the Challange


#1

Hi All, First post so I apologize if I screw up the posting. I’ve gone through and written what I thought was a viable solution to the challenge but whenever I run it I get an uncaught exception error. Here’s the selections of my code:

BNRStockHolding.h

[code]#import <Foundation/Foundation.h>

@interface BNRStockHolding : NSObject

@property (nonatomic) float purchaseSharePrice;
@property (nonatomic) float currentSharePrice;
@property (nonatomic) int numberOfShares;
@property (nonatomic) char *companyName;

  • (float)costInDollars; // purchaseSharePrice * numberOfShares
  • (float)valueInDollars; // currentSharePrice * numberOfShares

@end
[/code]

BNRStockHolding.m

[code]#import “BNRStockHolding.h”

@implementation BNRStockHolding

-(float)costInDollars
{
return _purchaseSharePrice * _numberOfShares;
}
-(float)valueInDollars
{
return _currentSharePrice * _numberOfShares;
}

@end[/code]

BNRForeignStockHolding.h

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

@interface BNRForeignStockHolding : BNRStockHolding

{
float conversionRate;
}

@property (nonatomic) float conversionRate;

@end[/code]

BNRForeignStockHolding.m

[code]@implementation BNRForeignStockHolding

  • (float) costInDollars
    {
    float costBeforeConversion = super.costInDollars;
    return costBeforeConversion * conversionRate;

}

  • (float) valueInDollars
    {
    float valueBeforeConversion = super.valueInDollars;
    return valueBeforeConversion * conversionRate;
    }

@end[/code]

And here’s main.m

[code]//
#import <Foundation/Foundation.h>
#import “BNRStockHolding.h”
#import “BNRForeignStockHolding.h”

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

@autoreleasepool {
    
    // Create three instances of BNRStockHolding
    BNRStockHolding *firstHolding = [[BNRStockHolding alloc] init];
    BNRStockHolding *secondHolding = [[BNRStockHolding alloc] init];
    BNRStockHolding *thirdHolding = [[BNRStockHolding alloc] init];
    
    // Set values for firstHolding
    firstHolding.purchaseSharePrice = 2.30;
    firstHolding.currentSharePrice = 4.50;
    firstHolding.numberOfShares = 40;
    firstHolding.companyName = "Google";
    
    // Set values for secondHolding
    secondHolding.purchaseSharePrice = 12.19;
    secondHolding.currentSharePrice = 10.56;
    secondHolding.numberOfShares = 90;
    secondHolding.companyName = "Apple";
    
    // Set values for thirdHolding
    thirdHolding.purchaseSharePrice = 45.10;
    thirdHolding.currentSharePrice  = 49.51;
    thirdHolding.numberOfShares = 210;
    thirdHolding.companyName = "Microsoft";
    
    // Create one instance of BNRForeignStockHolding
    BNRForeignStockHolding *firstForeignHolding = [[BNRForeignStockHolding alloc] init];
    
    // Set values for firstForeignHolding
    firstForeignHolding.purchaseSharePrice = 2.30;
    firstForeignHolding.currentSharePrice = 4.50;
    firstForeignHolding.numberOfShares = 40;
    firstForeignHolding.companyName = "Verstald LTD";
    firstForeignHolding.conversionRate = 0.94;
    
    // Create Mutable array then add the instances of BNRStockHolding
    NSMutableArray *stockPortfolio = [NSMutableArray array];
    [stockPortfolio addObject:firstHolding];
    [stockPortfolio addObject:secondHolding];
    [stockPortfolio addObject:thirdHolding];
    [stockPortfolio addObject:firstForeignHolding];
    
    // Calculate and Report their cost, value, and earnings
    for (BNRStockHolding *sh in stockPortfolio) {
        float cost = sh.costInDollars;
        float value = sh.valueInDollars;
        char *name = sh.companyName;
        NSLog(@"Your %s stocks cost %.2f at time of purchase, are now worth %.2f.", name, cost, value);
        
    for (BNRForeignStockHolding *fsh in stockPortfolio) {
        float cost = fsh.costInDollars;
        float value = fsh.valueInDollars;
        float cRate = fsh.conversionRate;
        char *name = fsh.companyName;
        NSLog(@"Your %s stocks cost %.2f at time of purchase, are now worth %.2f at a rate of %.2f", name, cost, value, cRate);
    }
}

}
return 0;
}[/code]

And here’s the error reciept I’m getting:

2014-02-15 19:55:21.979 Stocks[1172:303] Your Google stocks cost 92.00 at time of purchase, are now worth 180.00. 2014-02-15 19:55:22.001 Stocks[1172:303] -[BNRStockHolding conversionRate]: unrecognized selector sent to instance 0x100108fd0 2014-02-15 19:55:22.003 Stocks[1172:303] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[BNRStockHolding conversionRate]: unrecognized selector sent to instance 0x100108fd0' *** First throw call stack: ( 0 CoreFoundation 0x00007fff92bad41c __exceptionPreprocess + 172 1 libobjc.A.dylib 0x00007fff98171e75 objc_exception_throw + 43 2 CoreFoundation 0x00007fff92bb02ed -[NSObject(NSObject) doesNotRecognizeSelector:] + 205 3 CoreFoundation 0x00007fff92b0b5b2 ___forwarding___ + 1010 4 CoreFoundation 0x00007fff92b0b138 _CF_forwarding_prep_0 + 120 5 Stocks 0x000000010000173b main + 1835 6 libdyld.dylib 0x00007fff8ed085fd start + 1 7 ??? 0x0000000000000001 0x0 + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException

I’m really not sure whats going on here and any help would be much appreciated. I get that something is wrong with the conversionRate selector but I don’t get what or where to start with fixing it because compared to other solutions if found it looks like it should work. If anyone knows/sees anything and can even just point me in the direction of the problem or a fix I would be really grateful.


#2

[quote].. 2014-02-15 19:55:22.001 Stocks[1172:303] -[BNRStockHolding conversionRate]: unrecognized selector sent to instance 0x100108fd0 ...[/quote]
You forgot to define the property named conversionRate in BNRStockHolding, but you are sending conversionRate messages to all objects of type BNRStockHolding:

[quote] for (BNRForeignStockHolding *fsh in stockPortfolio) { ... float cRate = fsh.conversionRate; // <--- fsh is of type BNRStockHolding or BNRForeignStockHolding? ... }[/quote]
Only objects of type BNRForeignStockHolding understand that message:

[quote][code]#import <Foundation/Foundation.h>
#import “BNRStockHolding.h”

@interface BNRForeignStockHolding : BNRStockHolding

@property (nonatomic) float conversionRate;

@end[/code][/quote]


#3

So adding a declaration of the cRate property in the superclass BNRStockHolding fixed the error, so thanks for that. TBH I feel kind of dumb for not catching that but thanks to you I wont miss that again. Anyone have any advice on how to make this kind of a solution work?

// Calculate and Report their cost, value, and earnings for (BNRStockHolding *sh in stockPortfolio) { float cost = sh.costInDollars; float value = sh.valueInDollars; char *name = sh.companyName; NSLog(@"Your stock holding in %s cost %.2f at the time of purchase, and are now worth %.2f.", name, cost, value); if (some conditions that say if the for loop sees a BNRForeignStockHolding to run through the following loop) { for (BNRForeignStockHolding *fsh in stockPortfolio) { float cost = fsh.costIndollars; float value = fsh.valueInDollars; float cRate = fsh.conversionRate; char *name = fsh.companyName; NSLog(@"Your foreign stock holding in %s cost %.2f at time of purchase and are now worth %.2f. The relevant currency exhange rate is %.2f.", name, cost, value, crate); } } } }

I’m trying to think of a way to make the for loop check what the type of object its iterating in stockPortfolio but I can’t find anything online about iterating with a for loop and checking for differing object types. Maybe my googlefu is off today.


#4

Aslo grats on the 1000th post, should I feel honored?