BNRItems don't log destruction


#1

I’m at the beginning of the chapter, with the demonstration of ARC. I’ve added

- (void)dealloc { NSLog(@"Destroyed: %@", self); }
to BNRItem.m, and to main.m I added this:

but my console output ends with the message: "2012-07-05 15:48:14.640 RandomPossessions[33995:903] Setting items to nill…"
Can anyone tell me what I’m doing wrong? (xcode 4.2, OSX 10.6.8)

main.m[code]//
// main.m
// RandomPossessions(v2)
//
// Created by Kasofa on 6/15/12.
// Copyright © 2012 MyCompanyName. All rights reserved.
//

#import <Foundation/Foundation.h>

#import “BNRItem.h”

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

@autoreleasepool {
    
    // Create a mutable array object, store its address in items variable
    NSMutableArray *items = [[NSMutableArray alloc] init];
    
    for (int i = 0; i < 10; i++) {
        BNRItem *p = [BNRItem randomItem];
        [items addObject:p];
    }
    
    for (BNRItem *item in items) {
        NSLog(@"%@", item);
    }
    
    // Destroy the array pointed to by items
    NSLog(@"Setting items to nill...");
    items = nil;
}
return 0;

}

[/code]

BNRItem.h[code]//
// BNRItem.h
// RandomPossessions(v2)
//
// Created by Kasofa on 6/15/12.
// Copyright © 2012 MyCompanyName. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface BNRItem : NSObject
{
NSString *itemName;
NSString *serialNumber;
int valueInDollars;
NSDate *dateCreated;
}

  • (id)randomItem;
  • (id)initWithItemName:(NSString *) name
    valueInDollars:(int)value
    serialNumber:(NSString *)sNumber;

  • (void)setItemName:(NSString *)str;

  • (NSString *)itemName;

  • (void)setSerialNumber:(NSString *)str;

  • (NSString *)serialNumber;

  • (void)setValueInDollars:(int)i;

  • (int)valueInDollars;

  • (NSDate *)dateCreated;
    @end
    [/code]

BNRItem.m[code]//
// BNRItem.m
// RandomPossessions(v2)
//
// Created by Kasofa on 6/15/12.
// Copyright © 2012 MyCompanyName. All rights reserved.
//

#import “BNRItem.h”

@implementation BNRItem

  • (id)initWithItemName:(NSString *)name
    valueInDollars:(int)value
    serialNumber:(NSString *)sNumber
    {
    // Call the superclass’s designated initializer
    self = [super init];

    // Did the superclass’s designated initializer succeed?
    if (self) {
    // Give the instance variables initial values
    [self setItemName:name];
    [self setSerialNumber:sNumber];
    [self setValueInDollars:value];
    dateCreated = [[NSDate alloc] init];
    }

    // Return the address of the newly initialized object
    return self;
    }

  • (NSString *)description
    {
    NSString *descriptionString =
    [[NSString alloc] initWithFormat:@"%@ (%@): Worth $%d, recorded on %@",
    itemName,
    serialNumber,
    valueInDollars,
    dateCreated];

    return descriptionString;
    }

// itemname section

  • (void)setItemName:(NSString *)str
    {
    itemName = str;
    }
  • (NSString *)itemName
    {
    return itemName;
    }

// serialnumber section

  • (void)setSerialNumber:(NSString *)str
    {
    serialNumber = str;
    }

  • (NSString *)serialNumber
    {
    return serialNumber;
    }

// valueindollars section

  • (void)setValueInDollars:(int)i
    {
    valueInDollars = i;
    }

  • (int)valueInDollars
    {
    return valueInDollars;
    }

// created section

  • (NSDate *)dateCreated
    {
    return dateCreated;
    }

  • (id)init
    {
    return [self initWithItemName:@“Item"
    valueInDollars:0
    serialNumber:@”"];
    }

  • (id)randomItem
    {
    // Create an array of three adjectives
    NSArray *randomAdjectiveList = [NSArray arrayWithObjects:@“Fluffy”,
    @“Rusty”,
    @“Shiny”, nil];

    // Create an array of three nouns
    NSArray *randomNounList = [NSArray arrayWithObjects:@“Bear”,
    @“Spork”,
    @“Mac”, nil];
    NSInteger adjectiveIndex = rand() % [randomAdjectiveList count];
    NSInteger nounIndex = rand() % [randomNounList count];

    NSString *randomName = [NSString stringWithFormat:@"%@ %@",
    [randomAdjectiveList objectAtIndex:adjectiveIndex],
    [randomNounList objectAtIndex:nounIndex]];

    int randomValue = rand() % 100;

    NSString *randomSerialNumber = [NSString stringWithFormat:@"%c%c%c%c%c",
    ‘0’ + rand() % 10,
    ‘A’ + rand() % 26,
    ‘0’ + rand() % 10,
    ‘A’ + rand() % 26,
    ‘0’ + rand() % 10];
    BNRItem *newItem =
    [[self alloc] initWithItemName:randomName
    valueInDollars:randomValue
    serialNumber:randomSerialNumber];
    return newItem;

}

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

@end
[/code]

Thanks!


#2

I’m having the same issue. My first guess is that somehow my “items” array still has an owner somewhere. Unfortunately, if that is the case I can’t seem to see where.

I even tried starting from the solutions to chapter2 posted online. Still no luck.

Has anyone else had luck with this?


#3

Relax: there is nothing wrong with your code.

I have pasted, complied, and run your code:

//  main.m

#import <Foundation/Foundation.h>

@interface BNRItem : NSObject
{
    NSString *itemName;
    NSString *serialNumber;
    int valueInDollars;
    NSDate *dateCreated;
}

+ (id)randomItem;

- (id)initWithItemName:(NSString *) name
        valueInDollars:(int)value
          serialNumber:(NSString *)sNumber;

- (void)setItemName:(NSString *)str;
- (NSString *)itemName;

- (void)setSerialNumber:(NSString *)str;
- (NSString *)serialNumber;

- (void)setValueInDollars:(int)i;
- (int)valueInDollars;

- (NSDate *)dateCreated;
@end

int main (int argc, const char * argv[])
{
    
    @autoreleasepool {
        
        // Create a mutable array object, store its address in items variable
        NSMutableArray *items = [[NSMutableArray alloc] init];
        
        for (int i = 0; i < 10; i++) {
            BNRItem *p = [BNRItem randomItem];
            [items addObject:p];
        }
        
        for (BNRItem *item in items) {
            NSLog(@"%@", item);
        }
        
        // Destroy the array pointed to by items
        NSLog(@"Setting items to nill...");
        items = nil;
    }
    return 0;
}

@implementation BNRItem

- (id)initWithItemName:(NSString *)name
        valueInDollars:(int)value
          serialNumber:(NSString *)sNumber
{
    // Call the superclass's designated initializer
    self = [super init];
    
    // Did the superclass's designated initializer succeed?
    if (self) {
        // Give the instance variables initial values
        [self setItemName:name];
        [self setSerialNumber:sNumber];
        [self setValueInDollars:value];
        dateCreated = [[NSDate alloc] init];
    }
    
    // Return the address of the newly initialized object
    return self;
}

- (NSString *)description
{
    NSString *descriptionString =
    [[NSString alloc] initWithFormat:@"%@ (%@): Worth $%d, recorded on %@",
     itemName,
     serialNumber,
     valueInDollars,
     dateCreated];
    
    return descriptionString;
}

// itemname section
- (void)setItemName:(NSString *)str
{
    itemName = str;
}
- (NSString *)itemName
{
    return itemName;
}

// serialnumber section
- (void)setSerialNumber:(NSString *)str
{
    serialNumber = str;
}

- (NSString *)serialNumber
{
    return serialNumber;
}

// valueindollars section
- (void)setValueInDollars:(int)i
{
    valueInDollars = i;
}

- (int)valueInDollars
{
    return valueInDollars;
}

// created section
- (NSDate *)dateCreated
{
    return dateCreated;
}

- (id)init
{
    return [self initWithItemName:@"Item"
                   valueInDollars:0
                     serialNumber:@""];
}

+ (id)randomItem
{
    // Create an array of three adjectives
    NSArray *randomAdjectiveList = [NSArray arrayWithObjects:@"Fluffy",
                                    @"Rusty",
                                    @"Shiny", nil];
    
    // Create an array of three nouns
    NSArray *randomNounList = [NSArray arrayWithObjects:@"Bear",
                               @"Spork",
                               @"Mac", nil];
    NSInteger adjectiveIndex = rand() % [randomAdjectiveList count];
    NSInteger nounIndex = rand() % [randomNounList count];
    
    NSString *randomName = [NSString stringWithFormat:@"%@ %@",
                            [randomAdjectiveList objectAtIndex:adjectiveIndex],
                            [randomNounList objectAtIndex:nounIndex]];
    
    int randomValue = rand() % 100;
    
    NSString *randomSerialNumber = [NSString stringWithFormat:@"%c%c%c%c%c",
                                    '0' + rand() % 10,
                                    'A' + rand() % 26,
                                    '0' + rand() % 10,
                                    'A' + rand() % 26,
                                    '0' + rand() % 10];
    BNRItem *newItem =
    [[self alloc] initWithItemName:randomName
                    valueInDollars:randomValue
                      serialNumber:randomSerialNumber];
    return newItem;
    
}

- (void)dealloc
{
    NSLog(@"Destroyed: %@", self);
}
@end

And here is the output:

2012-07-27 21:11:20.786 Kasofa[69198:503] Rusty Spork (8Q2U8): Worth $73, recorded on 2012-07-27 11:41:20 +0000
2012-07-27 21:11:20.787 Kasofa[69198:503] Shiny Spork (5Y2V3): Worth $40, recorded on 2012-07-27 11:41:20 +0000
2012-07-27 21:11:20.788 Kasofa[69198:503] Rusty Spork (2F9Z7): Worth $40, recorded on 2012-07-27 11:41:20 +0000
2012-07-27 21:11:20.788 Kasofa[69198:503] Rusty Bear (8G5V6): Worth $99, recorded on 2012-07-27 11:41:20 +0000
2012-07-27 21:11:20.789 Kasofa[69198:503] Shiny Spork (3P9B1): Worth $10, recorded on 2012-07-27 11:41:20 +0000
2012-07-27 21:11:20.790 Kasofa[69198:503] Rusty Mac (6R5C1): Worth $93, recorded on 2012-07-27 11:41:20 +0000
2012-07-27 21:11:20.790 Kasofa[69198:503] Fluffy Spork (3E4O0): Worth $1, recorded on 2012-07-27 11:41:20 +0000
2012-07-27 21:11:20.791 Kasofa[69198:503] Fluffy Mac (3A6T4): Worth $30, recorded on 2012-07-27 11:41:20 +0000
2012-07-27 21:11:20.791 Kasofa[69198:503] Shiny Spork (8S3I1): Worth $77, recorded on 2012-07-27 11:41:20 +0000
2012-07-27 21:11:20.792 Kasofa[69198:503] Rusty Spork (4F6F9): Worth $65, recorded on 2012-07-27 11:41:20 +0000
2012-07-27 21:11:20.793 Kasofa[69198:503] Setting items to nill...
2012-07-27 21:11:20.793 Kasofa[69198:503] Destroyed: Rusty Spork (4F6F9): Worth $65, recorded on 2012-07-27 11:41:20 +0000
2012-07-27 21:11:20.794 Kasofa[69198:503] Destroyed: Shiny Spork (8S3I1): Worth $77, recorded on 2012-07-27 11:41:20 +0000
2012-07-27 21:11:20.795 Kasofa[69198:503] Destroyed: Fluffy Mac (3A6T4): Worth $30, recorded on 2012-07-27 11:41:20 +0000
2012-07-27 21:11:20.795 Kasofa[69198:503] Destroyed: Fluffy Spork (3E4O0): Worth $1, recorded on 2012-07-27 11:41:20 +0000
2012-07-27 21:11:20.796 Kasofa[69198:503] Destroyed: Rusty Mac (6R5C1): Worth $93, recorded on 2012-07-27 11:41:20 +0000
2012-07-27 21:11:20.796 Kasofa[69198:503] Destroyed: Shiny Spork (3P9B1): Worth $10, recorded on 2012-07-27 11:41:20 +0000
2012-07-27 21:11:20.797 Kasofa[69198:503] Destroyed: Rusty Bear (8G5V6): Worth $99, recorded on 2012-07-27 11:41:20 +0000
2012-07-27 21:11:20.798 Kasofa[69198:503] Destroyed: Rusty Spork (2F9Z7): Worth $40, recorded on 2012-07-27 11:41:20 +0000
2012-07-27 21:11:20.798 Kasofa[69198:503] Destroyed: Shiny Spork (5Y2V3): Worth $40, recorded on 2012-07-27 11:41:20 +0000
2012-07-27 21:11:20.799 Kasofa[69198:503] Destroyed: Rusty Spork (8Q2U8): Worth $73, recorded on 2012-07-27 11:41:20 +0000

The problem that you are seeing could be because of this: sometimes, when running under Xcode, a program exits too quickly before the output makes it to the console.

See the post: viewtopic.php?f=170&t=4731


#4

Searching around online I found a link with a possible explanation: https://discussions.apple.com/docs/DOC-3461

Because this chapter begins by creating a Mac OSX application, it seems that that some of the examples may not work as expected for people running Snow Leopard.

I’ll confirm by running my code on a friend’s Mac that is running Lion and report back.


#5

Ok, it’s confirmed. I just tried using the same exact code with OS X Lion and it works just fine.