Output didn't come out as expected for my challenge solution


#1

Hi guys, for some reasons my output didn’t come out as expected for my solutions. There are basically two problems:

  1. Why does it print out my foreign stock description twice for each foreign stock?
  2. Why does my information (no. of shares, value in dollars) do not show up on my foreign stock description?

Many thanks!!

First of all, here is my output:

2013-05-06 13:23:23.971 Stocks[4271:303] Portfolios: ( "<Portfolio 0: $0 in stocks>", "<Portfolio 1: $441 in stocks>", "<Portfolio 2: $376 in stocks>", "<Portfolio 3: $466 in stocks>", "<Portfolio 4: $0 in stocks>", "<Portfolio 5: $573 in stocks>", "<Portfolio 6: $550 in stocks>", "<Portfolio 7: $231 in stocks>", "<Portfolio 8: $0 in stocks>", "<Portfolio 9: $408 in stocks>" ) 2013-05-06 13:23:23.973 Stocks[4271:303] Removing a bank's portfolio 2013-05-06 13:23:23.974 Stocks[4271:303] deallocating <Portfolio 5: $573 in stocks> 2013-05-06 13:23:23.974 Stocks[4271:303] deallocating <Stock 3: Shares:43 Value:$258.000000 > 2013-05-06 13:23:23.975 Stocks[4271:303] deallocating <Stock 5: Shares:45 Value:$315.000000 > 2013-05-06 13:23:23.975 Stocks[4271:303] Removing all portfolios 2013-05-06 13:23:23.976 Stocks[4271:303] deallocating <Portfolio 0: $0 in stocks> 2013-05-06 13:23:23.976 Stocks[4271:303] deallocating <FStock 2: Shares:0 Value:$0.000000 > 2013-05-06 13:23:23.977 Stocks[4271:303] deallocating <FStock 2: Shares:0 Value:$0.000000 > 2013-05-06 13:23:23.977 Stocks[4271:303] deallocating <FStock 6: Shares:0 Value:$0.000000 > 2013-05-06 13:23:23.978 Stocks[4271:303] deallocating <FStock 6: Shares:0 Value:$0.000000 > 2013-05-06 13:23:23.978 Stocks[4271:303] deallocating <Portfolio 1: $441 in stocks> 2013-05-06 13:23:23.979 Stocks[4271:303] deallocating <Stock 9: Shares:49 Value:$441.000000 > 2013-05-06 13:23:23.995 Stocks[4271:303] deallocating <Portfolio 2: $376 in stocks> 2013-05-06 13:23:23.996 Stocks[4271:303] deallocating <Stock 7: Shares:47 Value:$376.000000 > 2013-05-06 13:23:23.996 Stocks[4271:303] deallocating <FStock 0: Shares:0 Value:$0.000000 > 2013-05-06 13:23:23.997 Stocks[4271:303] deallocating <FStock 0: Shares:0 Value:$0.000000 > 2013-05-06 13:23:23.997 Stocks[4271:303] deallocating <FStock 8: Shares:0 Value:$0.000000 > 2013-05-06 13:23:23.998 Stocks[4271:303] deallocating <FStock 8: Shares:0 Value:$0.000000 > 2013-05-06 13:23:23.999 Stocks[4271:303] deallocating <Portfolio 3: $466 in stocks> 2013-05-06 13:23:23.999 Stocks[4271:303] deallocating <Stock 0: Shares:40 Value:$180.000000 > 2013-05-06 13:23:24.000 Stocks[4271:303] deallocating <Stock 4: Shares:44 Value:$286.000000 > 2013-05-06 13:23:24.000 Stocks[4271:303] deallocating <FStock 4: Shares:0 Value:$0.000000 > 2013-05-06 13:23:24.001 Stocks[4271:303] deallocating <FStock 4: Shares:0 Value:$0.000000 > 2013-05-06 13:23:24.001 Stocks[4271:303] deallocating <Portfolio 4: $0 in stocks> 2013-05-06 13:23:24.001 Stocks[4271:303] deallocating <Portfolio 6: $550 in stocks> 2013-05-06 13:23:24.002 Stocks[4271:303] deallocating <Stock 1: Shares:41 Value:$205.000000 > ------ SKIP ------- 2013-05-06 13:23:24.008 Stocks[4271:303] deallocating <Stock 8: Shares:48 Value:$408.000000 > 2013-05-06 13:23:24.008 Stocks[4271:303] deallocating <FStock 3: Shares:0 Value:$0.000000 > 2013-05-06 13:23:24.009 Stocks[4271:303] deallocating <FStock 3: Shares:0 Value:$0.000000 >

Portfolio.h

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

@interface Portfolio : NSObject
{
int portfolioID;
NSMutableArray *stocks;
}

@property int portfolioID;

  • (void)addStocksObject:(StockHolding *)s;
    //- (void)addFStocksObject:(ForeignStockHolding *)f;
  • (unsigned int)valueOfStocks;

@end
[/code]

Portfolio.m

[code]#import “Portfolio.h”
#import “StockHolding.h”
#import “ForeignStockHolding.h”

@implementation Portfolio

@synthesize portfolioID;

  • (void)addStocksObject:(StockHolding *)s
    {
    // Is stock nil?
    if (!stocks) {

      // Create the array
      stocks = [[NSMutableArray alloc] init];
    

    }
    [stocks addObject:s];
    }

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

  • (NSString *)description
    {
    return [NSString stringWithFormat:@"<Portfolio %d: $%d in stocks>",
    [self portfolioID], [self valueOfStocks]];
    }

  • (void)dealloc
    {
    NSLog(@“deallocating %@”, self);
    }

@end
[/code]

StockHolding.h

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

@interface StockHolding : NSObject
{
NSString *label;
float purchaseSharePrice;
float currentSharePrice;
int numberOfShares;
}

@property (strong) NSString *label;
@property float purchaseSharePrice;
@property float currentSharePrice;
@property int numberOfShares;

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

@end[/code]

StockHolding.m

[code]#import “StockHolding.h”

@implementation StockHolding

@synthesize label, purchaseSharePrice, currentSharePrice, numberOfShares;

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

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

  • (NSString *)description
    {
    return [NSString stringWithFormat:@"<%@: Shares:%i Value:$%f >",
    [self label], [self numberOfShares], [self valueInDollars]];
    }

  • (void)dealloc
    {
    NSLog(@“deallocating %@”, self);
    }

@end[/code]

ForeignStockHolding.h

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

@interface ForeignStockHolding : StockHolding
{
float conversionRate;
}

@property float conversionRate;

@end
[/code]

ForeignStockHolding.m

[code]#import “ForeignStockHolding.h”

@implementation ForeignStockHolding

@synthesize conversionRate;

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

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

  • (NSString *)description
    {
    return [NSString stringWithFormat:@"<%@: Shares:%i Value:$%f >",
    [super label], [super numberOfShares], [self valueInDollars]];
    }

  • (void)dealloc
    {
    NSLog(@“deallocating %@”, self);
    }

@end
[/code]

main.m

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

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

@autoreleasepool {
    
    // Create an array of Portfolio objects
    NSMutableArray *portfolios = [[NSMutableArray alloc] init];
    
    for (int i = 0; i < 10; i++) {
        // Create an instance of Portfolio
        Portfolio *bank = [[Portfolio alloc] init];
        
        // Give the instance variables interesting values
        [bank setPortfolioID:i];
        
        [portfolios addObject:bank];
    }
    
    // Create 10 stocks
    for (int i = 0; i < 10; i++) {
        
        // Create a stock
        StockHolding *stock = [[StockHolding alloc] init];
        
        // Give it an interesting label
        NSString *currentLabel = [NSString stringWithFormat:@"Stock %d", i];
        [stock setLabel:currentLabel];
        [stock setPurchaseSharePrice:2.30 + i];
        [stock setCurrentSharePrice:4.50 + i * 0.5];
        [stock setNumberOfShares:40 + i];
        
        // Get a random number between 0 and 9 inclusive
        NSUInteger randomIndex = random() % [portfolios count];
        
        // Find that portfolio
        Portfolio *randomBank = [portfolios objectAtIndex:randomIndex];
        
        // Assign the stock to the bank
        [randomBank addStocksObject:stock];
        
    }
    
    // Create 10 foreign stocks
    for (int i = 0; i < 10; i++) {
        
        // Create a foreign stock
        ForeignStockHolding *fstock = [[ForeignStockHolding alloc] init];
        
        // Give it an interesting label
        NSString *currentLabel = [NSString stringWithFormat:@"FStock %d", i];
        [fstock setLabel:currentLabel];
        [fstock setPurchaseSharePrice:1.30 + i];
        [fstock setCurrentSharePrice:3.50 + i * 0.5];
        [fstock setConversionRate:0.94];
        
        // Get a random number between 0 and 9 inclusive
        NSUInteger randomIndex = random() % [portfolios count];
        
        // Find that portfolio
        Portfolio *randomBank = [portfolios objectAtIndex:randomIndex];
        
        // Assign the foreign stock to the bank
        [randomBank addStocksObject:fstock];
    }
    
    NSLog(@"Portfolios: %@", portfolios);
    
    NSLog(@"Removing a bank's portfolio");
    
    [portfolios removeObjectAtIndex:5];
    
    NSLog(@"Removing all portfolios");
    
    portfolios = nil;
}
return 0;

}
[/code]


#2

That’s because:

Each ForeignStockHolding object has two parts: StockHolding part and the Foreign part.

When a ForeignStockHolding object is released, its Foreign part’s dealloc method is run first then the StockHolding part’s dealloc method. Now having said that, what you will read next might confuse you. In both parts, self refers to the same object, the ForeignStockHolding object being released. It is important that you understand this subtlety.

If you are confused, print the address of the object in each dealloc method:

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

And see that they are the same. (Remember: addresses are always unique (no two addresses are the same) in a program.)


#3

Hi ibex10, thanks for your reply.

I have followed your advice and replaced your dealloc method to my ForeignStockHolding.m and StockHolding.m

Here is part of the output:

[code]2013-05-06 17:16:29.589 Stocks[5171:303] Removing a bank’s portfolio
2013-05-06 17:16:29.589 Stocks[5171:303] deallocating: Address (0x10010a8c0) <Portfolio 5: $573 in stocks>
2013-05-06 17:16:29.590 Stocks[5171:303] deallocating: Address (0x10010b3d0) <Stock 3: Shares:43 Value:$258.000000 >
2013-05-06 17:16:29.590 Stocks[5171:303] deallocating: Address (0x10010b480) <Stock 5: Shares:45 Value:$315.000000 >
2013-05-06 17:16:29.591 Stocks[5171:303] Removing all portfolios
2013-05-06 17:16:29.591 Stocks[5171:303] deallocating: Address (0x10010a7e0) <Portfolio 0: $0 in stocks>
2013-05-06 17:16:29.592 Stocks[5171:303] deallocating: Address (0x100108e60) <FStock 2: Shares:0 Value:$0.000000 >
2013-05-06 17:16:29.592 Stocks[5171:303] deallocating: Address (0x100108e60) <FStock 2: Shares:0 Value:$0.000000 >
2013-05-06 17:16:29.592 Stocks[5171:303] deallocating: Address (0x100104730) <FStock 6: Shares:0 Value:$0.000000 >
2013-05-06 17:16:29.593 Stocks[5171:303] deallocating: Address (0x100104730) <FStock 6: Shares:0 Value:$0.000000 >
2013-05-06 17:16:29.610 Stocks[5171:303] deallocating: Address (0x10010a880) <Portfolio 1: $441 in stocks>
2013-05-06 17:16:29.611 Stocks[5171:303] deallocating: Address (0x10010b600) <Stock 9: Shares:49 Value:$441.000000 >
2013-05-06 17:16:29.611 Stocks[5171:303] deallocating: Address (0x10010a8a0) <Portfolio 2: $376 in stocks>
2013-05-06 17:16:29.612 Stocks[5171:303] deallocating: Address (0x10010b4e0) <Stock 7: Shares:47 Value:$376.000000 >
2013-05-06 17:16:29.612 Stocks[5171:303] deallocating: Address (0x100107500) <FStock 0: Shares:0 Value:$0.000000 >
2013-05-06 17:16:29.613 Stocks[5171:303] deallocating: Address (0x100107500) <FStock 0: Shares:0 Value:$0.000000 >
2013-05-06 17:16:29.613 Stocks[5171:303] deallocating: Address (0x100102e50) <FStock 8: Shares:0 Value:$0.000000 >
2013-05-06 17:16:29.614 Stocks[5171:303] deallocating: Address (0x100102e50) <FStock 8: Shares:0 Value:$0.000000 >
2013-05-06 17:16:29.614 Stocks[5171:303] deallocating: Address (0x10010a8e0) <Portfolio 3: $466 in stocks>

[/code]

The addresses are indeed same for the “doubled” ForeignStockHolding objects. So I tried to remove the dealloc method in my ForeignStockHolding.m

and here is the output after I removed dealloc in ForeignStockHolding:

2013-05-06 17:26:34.253 Stocks[5222:303] Removing a bank's portfolio 2013-05-06 17:26:34.253 Stocks[5222:303] deallocating <Portfolio 5: $573 in stocks> 2013-05-06 17:26:34.254 Stocks[5222:303] deallocating: Address (0x10010b3e0) <Stock 3: Shares:43 Value:$258.000000 > 2013-05-06 17:26:34.255 Stocks[5222:303] deallocating: Address (0x10010b4a0) <Stock 5: Shares:45 Value:$315.000000 > 2013-05-06 17:26:34.255 Stocks[5222:303] Removing all portfolios 2013-05-06 17:26:34.256 Stocks[5222:303] deallocating <Portfolio 0: $0 in stocks> 2013-05-06 17:26:34.256 Stocks[5222:303] deallocating: Address (0x100109140) <FStock 2: Shares:0 Value:$0.000000 > 2013-05-06 17:26:34.257 Stocks[5222:303] deallocating: Address (0x100102800) <FStock 6: Shares:0 Value:$0.000000 > 2013-05-06 17:26:34.257 Stocks[5222:303] deallocating <Portfolio 1: $441 in stocks> 2013-05-06 17:26:34.258 Stocks[5222:303] deallocating: Address (0x10010b620) <Stock 9: Shares:49 Value:$441.000000 > 2013-05-06 17:26:34.258 Stocks[5222:303] deallocating <Portfolio 2: $376 in stocks> 2013-05-06 17:26:34.259 Stocks[5222:303] deallocating: Address (0x10010b500) <Stock 7: Shares:47 Value:$376.000000 > 2013-05-06 17:26:34.259 Stocks[5222:303] deallocating: Address (0x10010b7d0) <FStock 0: Shares:0 Value:$0.000000 > 2013-05-06 17:26:34.260 Stocks[5222:303] deallocating: Address (0x100104780) <FStock 8: Shares:0 Value:$0.000000 > 2013-05-06 17:26:34.260 Stocks[5222:303] deallocating <Portfolio 3: $466 in stocks> ------

Is this is the correct way to remove the redundancy? The reason I removed it because the ForeignStockHolding class inherits the dealloc method from StockHolding class, so it is unnecessary for ForeignStockHolding.m to have the dealloc method.


#4

In this simple example, you can get rid of both of the dealloc methods because you are not allocating any resources that ARC can’t handle. The methods are merely there to show you, by means of logging, that ARC machinery is working.

But make sure that, by the time you finish the book, you understand why and when we need to use dealloc methods because one day you might need them.


#5

I see, thanks! I’ll take a second look of ARC and dealloc.

By the way, how about my second question. Do you have any idea why did it happen to my scripts?