Annoyance in Chapter 20 Challenge


#1

I cleaned up the Stock code to remove extra code using what we learned about properties in Chapter 19. I’m getting 99% of what I want to work working, but my stocks are printing memory addresses rather than the stock names. I’m baffled as to why, but I know it’s something very simple. Here’s my code:

BNRStockHolding.h

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

@interface BNRStockHolding : NSObject

@property (nonatomic) float purchaseSharePrice;
@property (nonatomic) float currentSharePrice;
@property (nonatomic) int numberOfShares;

// ADD STOCKS TO ARRAY

  • (void)addStocksToArray:(NSMutableArray *)stockHoldings;

  • (float)costInDollars;

  • (float)valueInDollars;

@end[/code]

BNRStockHolding.m

[code]#import “BNRStockHolding.h”

@implementation BNRStockHolding

// purchchase info

-(void)addStocksToArray:(NSMutableArray *)stockHoldings
{
[stockHoldings addObject: self];
}

-(float)costInDollars
{
return self.purchaseSharePrice * self.numberOfShares;
}

-(float)valueInDollars
{
return self.currentSharePrice * self.numberOfShares;
}

@end [/code]

main.m

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

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

@autoreleasepool {
    
    // Create array for stock holdings NEED TO ADD STOCKS TO ARRAY
    NSMutableArray *stockHoldings = [NSMutableArray array];
    
    // Create instance of BNRStockHolding for stock1, stock2, stock3
    BNRStockHolding *stock1 = [[BNRStockHolding alloc] init];
    BNRStockHolding *stock2 = [[BNRStockHolding alloc] init];
    BNRStockHolding *stock3 = [[BNRStockHolding alloc] init];
    

    // Give the instance variables values using setters
    stock1.purchaseSharePrice = 2.30;
    stock1.currentSharePrice = 4.50;
    stock1.numberOfShares = 40;
    [stockHoldings addObject:stock1];
    
    stock2.purchaseSharePrice = 12.19;
    stock2.currentSharePrice = 10.56;
    stock2.numberOfShares = 90;
    [stockHoldings addObject:stock2];
    
    stock3.purchaseSharePrice = 45.10;
    stock3.currentSharePrice = 10.50;
    stock3.numberOfShares = 210;
    [stockHoldings addObject:stock3];
    
    // Print list of stocks w/ costInDollars and valueInDollars
    for (BNRStockHolding *stock in stockHoldings) {
        NSLog (@"%@: costInDollars %.2f valueInDollars %.2f", stock, stock.costInDollars, stock.valueInDollars);
    }
    
}
return 0;

}[/code]

I get memory addresses where I’d like the NSString containing the stock name to go:
<BNRStockHolding: 0x1001002f0>: costInDollars 92.00 valueInDollars 180.00
<BNRStockHolding: 0x100102110>: costInDollars 1097.10 valueInDollars 950.40
<BNRStockHolding: 0x100108110>: costInDollars 9471.00 valueInDollars 2205.00
Program ended with exit code: 0


#2

On your main.m within your for loop you output format is %@ for each BNRStockHolding.
The %@ token is asking each BNRStockHolding to describe itself hence the [quote]<BNRStockHolding: 0x1001002f0>[/quote] output you are getting.
Im also new to Objective C so take my reasoning with a grain of salt. :smiley:


#3

I am also new, but I do not believe you want to be creating or adjusting arrays in your header (.h) or (.m) files. For this assignment anyway, I think you want to keep your array manipulations in the main file.

I am open to hearing from others on this issue.


#4

I just added an extra instance variable called nameOfStock and set the name when defining a new stock.
Example:

BNRStockHolding.h

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

@interface BNRStockHolding : NSObject

@property (nonatomic) float purchaseSharePrice;
@property (nonatomic) float currentSharePrice;
@property (nonatomic) int numberOfShares;
@property (nonatomic) NSString *nameOfStock;

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

@end
[/code]

main.m

BNRForeignStockHolding *nflx = [[BNRForeignStockHolding alloc]init]; [nflx setNameOfStock:@"NFLX"]; [nflx setPurchaseSharePrice:193.00]; [nflx setCurrentSharePrice:487.24]; [nflx setNumberOfShares:100]; [nflx setConversionRate:1.4];


#5

[quote=“dcdude1776”]I cleaned up the Stock code to remove extra code using what we learned about properties in Chapter 19. I’m getting 99% of what I want to work working, but my stocks are printing memory addresses rather than the stock names. I’m baffled as to why, but I know it’s something very simple. Here’s my code:

BNRStockHolding.h

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

@interface BNRStockHolding : NSObject

@property (nonatomic) float purchaseSharePrice;
@property (nonatomic) float currentSharePrice;
@property (nonatomic) int numberOfShares;

// ADD STOCKS TO ARRAY

  • (void)addStocksToArray:(NSMutableArray *)stockHoldings;

  • (float)costInDollars;

  • (float)valueInDollars;

@end[/code]

BNRStockHolding.m

[code]#import “BNRStockHolding.h”

@implementation BNRStockHolding

// purchchase info

-(void)addStocksToArray:(NSMutableArray *)stockHoldings
{
[stockHoldings addObject: self];
}

-(float)costInDollars
{
return self.purchaseSharePrice * self.numberOfShares;
}

-(float)valueInDollars
{
return self.currentSharePrice * self.numberOfShares;
}

@end [/code]

main.m

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

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

@autoreleasepool {
    
    // Create array for stock holdings NEED TO ADD STOCKS TO ARRAY
    NSMutableArray *stockHoldings = [NSMutableArray array];
    
    // Create instance of BNRStockHolding for stock1, stock2, stock3
    BNRStockHolding *stock1 = [[BNRStockHolding alloc] init];
    BNRStockHolding *stock2 = [[BNRStockHolding alloc] init];
    BNRStockHolding *stock3 = [[BNRStockHolding alloc] init];
    

    // Give the instance variables values using setters
    stock1.purchaseSharePrice = 2.30;
    stock1.currentSharePrice = 4.50;
    stock1.numberOfShares = 40;
    [stockHoldings addObject:stock1];
    
    stock2.purchaseSharePrice = 12.19;
    stock2.currentSharePrice = 10.56;
    stock2.numberOfShares = 90;
    [stockHoldings addObject:stock2];
    
    stock3.purchaseSharePrice = 45.10;
    stock3.currentSharePrice = 10.50;
    stock3.numberOfShares = 210;
    [stockHoldings addObject:stock3];
    
    // Print list of stocks w/ costInDollars and valueInDollars
    for (BNRStockHolding *stock in stockHoldings) {
        NSLog (@"%@: costInDollars %.2f valueInDollars %.2f", stock, stock.costInDollars, stock.valueInDollars);
    }
    
}
return 0;

}[/code]

I get memory addresses where I’d like the NSString containing the stock name to go:
<BNRStockHolding: 0x1001002f0>: costInDollars 92.00 valueInDollars 180.00
<BNRStockHolding: 0x100102110>: costInDollars 1097.10 valueInDollars 950.40
<BNRStockHolding: 0x100108110>: costInDollars 9471.00 valueInDollars 2205.00
Program ended with exit code: 0[/quote]

u have to override the description method implementation (BNRStockHolding.m)
try out and check the output: NSLog (@"%@: costInDollars %.2f valueInDollars %.2f", stock, stock.costInDollars, stock.valueInDollars);


#6

If you want to have the stock name show, do the following.

  1. Edit your .h file to include the following property:

@property (nonatomic) NSString *nameOfStock;

  1. Go back into main.m and add:

stock1.nameOfStock = @“Stock 1”;
stock2.nameOfStock = @“Stock 2”;
stock3.nameOfStock = @“Stock 3”;

  1. Now that you have given a name string to each of the stocks, you need to make sure that it returns the value of the string. Override the description of NSString in the BNRStockHolding.m file with:
  • (NSString *)description
    {
    return [NSString stringWithFormat:@"%@", self.nameOfStock];
    }
  1. Now run the program and you will see that when you call stock like you do in NSLog, it gives you the value of the string instead of the address of stock.