Stupid question with easy answer


#1

I’m working my way through Chapter 2 and I’ve gotten stuck on page 58. You have the power to save my MacBook Air from being thrown across the room. I know it’s a typo or something profoundly stupid, but I can’t figure it out!!!

I’m getting “No known class method for selector ‘randomItem’”. Whiskey Tango Foxtrot! I typed in the code ver-***ing-batim from the book. My code follows:

BNRItem.h

#import <Foundation/Foundation.h>

@interface BNRItem : NSObject

{
    NSString *_itemName;
    NSString *_serialNumber;
    int _valueInDollars;
    NSDate *_dateCreated;
}

// Designated initializer for BNRItem
- (instancetype)initWithItemName:(NSString *)name
                 valueInDollars:(int)value
                   serialNumber:(NSString *)sNumber;

- (instancetype)initWithItemName:(NSString *)name;

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

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

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

- (NSDate *)dateCreated;

@end

BNRItem.m

[code] NSInteger adjectiveIndex = arc4random() % [randomAdjectiveList count];
NSInteger nounIndex = arc4random() % [randomNounList count];

// Note the NSInteger is not an object, but a type definition
// for "long"

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

int randomValue = arc4random() % 100;

NSString *randomSerialNumber = [NSString stringWithFormat:@"%c%c%c%c%c",
                                '0' + arc4random() % 10,
                                'A' + arc4random() % 26,
                                '0' + arc4random() % 10,
                                'A' + arc4random() % 26,
                                '0' + arc4random() % 10];

BNRItem *newItem = [[self alloc] initWithItemName:randomName
                                   valueInDollars:randomValue
                                     serialNumber:randomSerialNumber];

return newItem;

}

  • (instancetype)initWithItemName:(NSString *)name
    {
    return [self initWithItemName:name
    valueInDollars:0
    serialNumber:@""];
    }

  • (instancetype)init
    {
    return [self initWithItemName:@“Item”];
    }

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

    return descriptionString;
    }

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

  • (NSString *)itemName
    {
    return _itemName;
    }

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

  • (NSString *)serialNumber
    {
    return _serialNumber;
    }

  • (void)setValueInDollars:(int)v
    {
    _valueInDollars = v;
    }

  • (int)valueInDollars
    {
    return _valueInDollars;
    }

  • (NSDate *)dateCreated
    {
    return _dateCreated;
    }

@end
[/code]

main.m

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

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

@autoreleasepool {
    
    // Create NSMutableArray called 'items'
    NSMutableArray *items = [[NSMutableArray alloc]init];
    
    for (int i = 0; i < 10; i++) {
        BNRItem *item = [BNRItem randomItem];
        [items addObject:item];
    }
    
    for (BNRItem *item in items) {
        NSLog(@"%@", item);
    }
    
    
    // Destroy the mutable array object;
    items = nil;
}
return 0;

}

[/code]


#2

Did you by any chance not copy the entire BNRItem.m?
The error message basically says that it can’t find the class method randomItem in the header file of BNRItem.
Fact is that I don’t see the line + (instancetype)randomItem; in your BNRItem.h, nor the complete implementation in the BNRItem.m. But that could be a case of not copy pasting the full file.

If you have implemented + (instancetype)randomItem; in your BNRItem.m, all you have to do is simply add the decleration in the .h file and it should work!

This is what my BNRItem.h looks like:

[code]//
// BNRItem.h
// RandomItems
//
// Created by Arthur Zwitser on 19-03-14.
// Copyright © 2014 Big Nerd Ranch. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface BNRItem : NSObject

@property (nonatomic, copy) NSString *itemName;
@property (nonatomic, copy) NSString *serialNumber;
@property (nonatomic) int valueInDollars;
@property (nonatomic, readonly) NSDate *dateCreated;

// Designated initializer for BNRItem

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

  • (instancetype)initWithItemName:(NSString *)name;

@end
[/code]


#3

Thank you, Arthur! I knew it was something stupid! I didn’t have it in my header file…just the implementation file. Total rookie mistake. Thank you so much!