Challenge Solved - But a ? about writing an array


#1

I’ve solved the challenge at the end of this chapter successfully. I created a Portfolio class that can hold my StockHolding class (which includes the variables from the Chapter 18 challenge such as purchasePrice, currentPrice, etc). I wanted to take it one step further, so when my program runs, not only would it give me the value of the stocks in the portfolio, BUT it would show which stocks make up the value. I’ve actually got it working, but I’m having issues with the output format.

 "<Portfolio 3 has a value of $494 and it's assets are: (\n    \"<Stock 0: 25 shares>\",\n    \"<Stock 4: 45 shares>\"\n)>"

What I’m having trouble with is why "\n " is being included within this output. I don’t actually have any instances in my code where I include “\n”


#2

\n is the escape sequence which indicates a new line. I’m not sure off-hand what you could do to produce such output, but it’s likely a simple oversight.

If you’ll post your code, we’ll take a look; probably someone already knows what would cause this.


#3

Here’s my main…

[code]//
// main.m
// Stocks
//
// Created by Chris H on 1/23/12.
// Copyright © 2012 MyCompanyName. All rights reserved.
//

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

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

@autoreleasepool {
    
    // insert code here...
    NSLog(@"Hello, World!");
    
    //srandom((int)time(NULL));
    
    // Create an array of Portfolio objects
    NSMutableArray *portfolios = [[NSMutableArray alloc]init];
    for (int i = 0; i < 10; i++) {
        
        Portfolio *portfolio = [[Portfolio alloc]init];
        
        // Give the portfolio object a name
        [portfolio setPortfolioLabel:i];
        
        [portfolios addObject:portfolio];
        
    }
    
    // Create 10 stock objects
    for (int i = 0; i < 10; i++) {
        
        // Create an instance of StockHolding
        StockHolding *sHolder = [[StockHolding alloc] init];
        
        // Give the instance variable interesting values
        NSString *currentStockLabel = [NSString stringWithFormat:@"Stock %d", i];
        
        [sHolder setStockLabel:currentStockLabel];
        [sHolder setPurchaseSharePrice:3.50 + i];
        [sHolder setCurrentSharePrice:4.50 + i];
        [sHolder setNumberOfShares:25 + i * 5];
        
        // Get a random number
        NSUInteger randomIndex = random() % [portfolios count];
        
        // Find that portfolio
        Portfolio *randomPortfolio = [portfolios objectAtIndex:randomIndex];
        
        // Assign the stockHolder to the Portfolio
        [randomPortfolio addStockingObject:sHolder];
    }
        
    NSLog(@"Portfolio Information: %@", portfolios);
    
        
    // add some more info about the portfolios here
    
    NSLog(@"Giving up ownership of one portfolio");
    
    [portfolios removeObjectAtIndex:5];
    
    NSLog(@"Giving up ownership of array");
    portfolios = nil;

}
return 0;
}
[/code]

Here’s my Portfolio.m class


#import "Portfolio.h"
#import "StockHolding.h"

@implementation Portfolio

@synthesize portfolioLabel;

- (void)addStockingObject:(StockHolding *)a {
    // Is Stocks nil?
    if (!stockHoldingArray) {
        
        // Create the array
        stockHoldingArray = [[NSMutableArray alloc] init];   
    }
    [stockHoldingArray addObject:a];
}

- (unsigned int)valueOfStocks {
    
    // Sum up the value of the stocks
    unsigned int sum = 0;
    
    for (StockHolding *a in stockHoldingArray) {
        sum += [a valueInDollars];
    }
    return sum;
}

 - (NSString *)description {
     return [NSString stringWithFormat:@"<Portfolio %d has a value of $%d and it's assets are: %@>", [self portfolioLabel], [self valueOfStocks], stockHoldingArray];
     
 }
 
 - (void)dealloc {
 NSLog(@"deallocating %@", self);
 }

And here’s my StockHolding.m class…


//
//  StockHolding.m
//  Stocks
//
//  Created by Chris H on 1/23/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "StockHolding.h"

@implementation StockHolding 

@synthesize purchaseSharePrice, currentSharePrice, numberOfShares, stockLabel;

- (float)costInDollars {
    return purchaseSharePrice * numberOfShares;
}
- (float)valueInDollars {
    return currentSharePrice * numberOfShares;
}

- (NSString *)description {
    return [NSString stringWithFormat:@"<%@: %d shares>", [self stockLabel], [self numberOfShares]];
}

- (void)dealloc {
    NSLog(@"deallocating %@", self);
}

@end

#4

I’m still not quite sure of the details, but it’s clear that the array’s description method is doing its best to convert a list into a string by inserting line breaks. What I don’t know is why those line breaks are being represented as literal \n escape characters instead of being rendered as line breaks.

I certainly wouldn’t stress about it; I don’t see any indication you’re doing anything wrong. In a “real” program, you wouldn’t rely on description methods from complex objects in Apple’s libraries for anything other than debugging output.

You might try changing this line:

     return [NSString stringWithFormat:@"<Portfolio %d has a value of $%d and it's assets are: %@>", [self portfolioLabel], [self valueOfStocks], stockHoldingArray];

To:

     return [NSString stringWithFormat:@"<Portfolio %d has a value of $%d and it's assets are: %s>", [self portfolioLabel], [self valueOfStocks], [stockHoldingArray description]];

But it should give you the same results.


#5

Yeah, same results but worth a shot. I was trying to Google why there’d be extra line-breaks in there - no luck. Thanks for the advice though. I figured overriding the description method to feed out my own results wouldn’t be a situation I’d have to deal with when I start coming making my own iOS apps.