Only certain stocks deallocating in challenge


#1

I’m having an issue with my code for the challenge in chapter 19. Here is my code:

Portfolio.h

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

@interface Portfolio : NSObject
{
    NSMutableArray *stockHoldings;
}

@property (strong) NSMutableArray *stockHoldings;

- (void)addStockHoldingsObject:(StockHolding *)s;

- (unsigned int)valueOfPortfolio;

@end

Portfolio.m

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

@implementation Portfolio

@synthesize stockHoldings;

- (void)addStockHoldingsObject:(StockHolding *)s
{
    // Is stockHoldings nil?
    if (!stockHoldings) {
        
        //Create the array
        stockHoldings = [[NSMutableArray alloc] init];
    }
    [stockHoldings addObject:s];
}

- (unsigned int)valueOfPortfolio
{
    // Sum up the resale value of the assets
    unsigned int sum = 0;
    for (StockHolding *s in stockHoldings) {
        sum += [s valueInDollars];
    }
    return sum;
}

-(NSString *)description
{
    return [NSString stringWithFormat:@"%@>", [self stockHoldings]];
}

-(void)dealloc
{
    NSLog(@"deallocating portfolio");
}

@end

StockHolding.h

#import <Foundation/Foundation.h>

@interface StockHolding : NSObject
{
    float purchaseSharePrice;
    float curretnSharePrice;
    int numberOfShares;
}

@property float purchaseSharePrice;
@property float currentSharePrice;
@property int numberOfShares;

- (float)costInDollars;
- (float)valueInDollars;

-(void) setPurchaseSharePrice:(float)p setCurrentSharePrice: (float)c setNumberOfShares: (int)n;


@end

StockHolding.m

#import "StockHolding.h"

@implementation StockHolding

@synthesize purchaseSharePrice, currentSharePrice, numberOfShares;

-(void) setPurchaseSharePrice:(float)p setCurrentSharePrice: (float)c setNumberOfShares: (int)n
{
    purchaseSharePrice = p;
    currentSharePrice = c;
    numberOfShares = n;
}

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

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

-(NSString *) description
{
    return [NSString stringWithFormat:@"<Stock: Original value: $%.2f, Current value: $%.2f, Number of Shares: %i>",
            [self purchaseSharePrice], [self currentSharePrice], [self numberOfShares]];
}

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

@end

main.m

#import <Foundation/Foundation.h>
#import "ForeignStockHolding.h"
#import "Portfolio.h"

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        
        Portfolio *portfolio = [[Portfolio alloc] init];
        
        StockHolding *stock1 = [[StockHolding alloc] init];
        StockHolding *stock2 = [[StockHolding alloc] init];
        StockHolding *stock3 = [[StockHolding alloc] init];
        // ForeignStockHolding *stock4 = [[ForeignStockHolding alloc] init];
        
        [stock1 setPurchaseSharePrice:2.30
                 setCurrentSharePrice:4.50
                    setNumberOfShares:40];
        
        [stock2 setPurchaseSharePrice:12.19
                 setCurrentSharePrice:10.56
                    setNumberOfShares:90];
        
        [stock3 setPurchaseSharePrice:45.10
                 setCurrentSharePrice:49.51
                    setNumberOfShares:210];
        
        /*
        [stock4 setPurchaseSharePrice:2.30
                 andCurrentSharePrice:4.50
                    andNumberOfShares:40];
            [stock4 setConversionRate:0.94];
        */
        
        [portfolio addStockHoldingsObject:stock1];
        [portfolio addStockHoldingsObject:stock2];
        [portfolio addStockHoldingsObject:stock3];
        
        for (int i = 0; i < 10; ++i) {
            StockHolding *stock = [[StockHolding alloc] init];
            
            [stock setPurchaseSharePrice:random() % 33
                    setCurrentSharePrice:random() % 66
                       setNumberOfShares:rand() % 99];
            
            [portfolio addStockHoldingsObject:stock];
        }
        
        unsigned int i = 1;
        for (StockHolding *s in [portfolio stockHoldings] ) {
            NSLog(@"Stock %d: Original value: $%.2f, Current value: $%.2f, Number of Shares: %d",
                  i++, [s purchaseSharePrice], [s currentSharePrice], [s numberOfShares]);
        }
        
        // NSLog(@"Portfolio: %@", portfolio);
        
        NSLog(@"Value of Portfolio: $%d\n\n",
              [portfolio valueOfPortfolio]);
        
        NSLog(@"Giving up ownership of one stock from portfolio");
        [[portfolio stockHoldings] removeObjectAtIndex:0];
        
        NSLog(@"Giving up ownership of array");
        portfolio = nil;
         
    }
    return 0;
}

(I left out the ForeignStockHolding class for the sake of brevity. I plan on introducing it once I solve this problem. It’s contents have nothing to do with the problem. It is imported in main.m, but the instance of a ForeignStockHolding is commented out, so it is the same as if I had just imported the StockHolding class)

This is the problem: when I remove the 0th/1st/2nd object from the portfolio, it doesn’t deallocate. However, if I remove any other one (e.g. 9th), it does.

(The outputs beneath are only small segments of the whole)

Output when removeObjectAtIndex:0

2013-08-19 01:08:40.748 Stocks[15605:303] Giving up ownership of one stock from portfolio
2013-08-19 01:08:40.748 Stocks[15605:303] Giving up ownership of array
2013-08-19 01:08:40.748 Stocks[15605:303] deallocating portfolio

Output when removeObjectAtIndex:9

2013-08-19 01:29:25.020 Stocks[15647:303] Giving up ownership of one stock from portfolio
2013-08-19 01:29:25.021 Stocks[15647:303] deallocating <Stock: Original value: $5.00, Current value: $25.00, Number of Shares: 24>
2013-08-19 01:29:25.022 Stocks[15647:303] Giving up ownership of array
2013-08-19 01:29:25.022 Stocks[15647:303] deallocating portfolio

Now, I do realize that the first 3 stocks are added to the portfolio in a different manner than the other 10, however, I do not understand why that makes a difference.

That’s not all though; here’s where I get really perplexed. As you can see in main.m, I have commented out the line where the portfolio describes itself. However, if I uncomment it and move it beneath the line where I remove the object at index 0, like so:

        NSLog(@"Giving up ownership of one stock from portfolio");
        [[portfolio stockHoldings] removeObjectAtIndex:0];
        
        NSLog(@"Portfolio: %@", portfolio);
        
        NSLog(@"Giving up ownership of array");
        portfolio = nil;

I get the following output (entire output):

2013-08-19 01:33:19.781 Stocks[15668:303] Stock 1: Original value: $2.30, Current value: $4.50, Number of Shares: 40
2013-08-19 01:33:19.783 Stocks[15668:303] Stock 2: Original value: $12.19, Current value: $10.56, Number of Shares: 90
2013-08-19 01:33:19.783 Stocks[15668:303] Stock 3: Original value: $45.10, Current value: $49.51, Number of Shares: 210
2013-08-19 01:33:19.784 Stocks[15668:303] Stock 4: Original value: $28.00, Current value: $10.00, Number of Shares: 76
2013-08-19 01:33:19.784 Stocks[15668:303] Stock 5: Original value: $6.00, Current value: $13.00, Number of Shares: 34
2013-08-19 01:33:19.785 Stocks[15668:303] Stock 6: Original value: $23.00, Current value: $37.00, Number of Shares: 77
2013-08-19 01:33:19.785 Stocks[15668:303] Stock 7: Original value: $22.00, Current value: $6.00, Number of Shares: 83
2013-08-19 01:33:19.786 Stocks[15668:303] Stock 8: Original value: $3.00, Current value: $1.00, Number of Shares: 85
2013-08-19 01:33:19.786 Stocks[15668:303] Stock 9: Original value: $8.00, Current value: $7.00, Number of Shares: 80
2013-08-19 01:33:19.786 Stocks[15668:303] Stock 10: Original value: $5.00, Current value: $25.00, Number of Shares: 24
2013-08-19 01:33:19.787 Stocks[15668:303] Stock 11: Original value: $29.00, Current value: $4.00, Number of Shares: 44
2013-08-19 01:33:19.787 Stocks[15668:303] Stock 12: Original value: $9.00, Current value: $54.00, Number of Shares: 53
2013-08-19 01:33:19.788 Stocks[15668:303] Stock 13: Original value: $13.00, Current value: $22.00, Number of Shares: 37
2013-08-19 01:33:19.788 Stocks[15668:303] Value of Portfolio: $21173

2013-08-19 01:33:19.788 Stocks[15668:303] Giving up ownership of one stock from portfolio
2013-08-19 01:33:19.789 Stocks[15668:303] Portfolio: (
    "<Stock: Original value: $12.19, Current value: $10.56, Number of Shares: 90>",
    "<Stock: Original value: $45.10, Current value: $49.51, Number of Shares: 210>",
    "<Stock: Original value: $28.00, Current value: $10.00, Number of Shares: 76>",
    "<Stock: Original value: $6.00, Current value: $13.00, Number of Shares: 34>",
    "<Stock: Original value: $23.00, Current value: $37.00, Number of Shares: 77>",
    "<Stock: Original value: $22.00, Current value: $6.00, Number of Shares: 83>",
    "<Stock: Original value: $3.00, Current value: $1.00, Number of Shares: 85>",
    "<Stock: Original value: $8.00, Current value: $7.00, Number of Shares: 80>",
    "<Stock: Original value: $5.00, Current value: $25.00, Number of Shares: 24>",
    "<Stock: Original value: $29.00, Current value: $4.00, Number of Shares: 44>",
    "<Stock: Original value: $9.00, Current value: $54.00, Number of Shares: 53>",
    "<Stock: Original value: $13.00, Current value: $22.00, Number of Shares: 37>"
)>
2013-08-19 01:33:19.790 Stocks[15668:303] Giving up ownership of array
2013-08-19 01:33:19.790 Stocks[15668:303] deallocating portfolio
2013-08-19 01:33:19.790 Stocks[15668:303] deallocating <Stock: Original value: $2.30, Current value: $4.50, Number of Shares: 40>
2013-08-19 01:33:19.791 Stocks[15668:303] deallocating <Stock: Original value: $12.19, Current value: $10.56, Number of Shares: 90>
2013-08-19 01:33:19.791 Stocks[15668:303] deallocating <Stock: Original value: $45.10, Current value: $49.51, Number of Shares: 210>
2013-08-19 01:33:19.792 Stocks[15668:303] deallocating <Stock: Original value: $28.00, Current value: $10.00, Number of Shares: 76>
2013-08-19 01:33:19.792 Stocks[15668:303] deallocating <Stock: Original value: $6.00, Current value: $13.00, Number of Shares: 34>
2013-08-19 01:33:19.792 Stocks[15668:303] deallocating <Stock: Original value: $23.00, Current value: $37.00, Number of Shares: 77>
2013-08-19 01:33:19.793 Stocks[15668:303] deallocating <Stock: Original value: $22.00, Current value: $6.00, Number of Shares: 83>
2013-08-19 01:33:19.793 Stocks[15668:303] deallocating <Stock: Original value: $3.00, Current value: $1.00, Number of Shares: 85>
2013-08-19 01:33:19.794 Stocks[15668:303] deallocating <Stock: Original value: $8.00, Current value: $7.00, Number of Shares: 80>
2013-08-19 01:33:19.795 Stocks[15668:303] deallocating <Stock: Original value: $5.00, Current value: $25.00, Number of Shares: 24>
2013-08-19 01:33:19.796 Stocks[15668:303] deallocating <Stock: Original value: $29.00, Current value: $4.00, Number of Shares: 44>
2013-08-19 01:33:19.796 Stocks[15668:303] deallocating <Stock: Original value: $9.00, Current value: $54.00, Number of Shares: 53>
2013-08-19 01:33:19.796 Stocks[15668:303] deallocating <Stock: Original value: $13.00, Current value: $22.00, Number of Shares: 37>

If you look closely, you will notice that the 0th stock was included in the portfolio when I looped through it, then, after we attempted to deallocate it, it did not appear when portfolio described itself despite the console not telling us that it had been deallocated, then when we deallocate the entire portfolio, it reappears and properly deallocates itself.

I am honestly stumped by this one. I have absolutely no idea why this is happening. I would rather not ignore the problem as I am really curious to find out what is wrong.

Any help appreciated.

Ben


#2

Increment the reference count:

StockHolding *stock1 = [[StockHolding alloc] init];
StockHolding *stock2 = [[StockHolding alloc] init];
StockHolding *stock3 = [[StockHolding alloc] init];

Reference count == 1.

Increment the reference count again:

[portfolio addStockHoldingsObject:stock1];
[portfolio addStockHoldingsObject:stock2];
[portfolio addStockHoldingsObject:stock3];

Reference count == 2.

Therefore if you delete any of the first three stocks from the portfolio, they won’t be deallocated until the program exits.

Set them to nil after adding them to the portfolio.

Decrement the reference count:

[portfolio addStockHoldingsObject:stock1];
stock1 = nil;
[portfolio addStockHoldingsObject:stock2];
stock2 = nil;
[portfolio addStockHoldingsObject:stock3];
stock3 = nil;

Reference count == 1.

Now if you delete them from the portfolio, they should be deallocated.


#3

Thanks, that clears a lot up. However, I still don’t understand why the stock (1,2, or 3) disappeared when I get the description of the portfolio and then reappeared once I set the portfolio to nil (doesn’t happen anymore after applying recommended changes).