Befuddled


#1

I have been tearing my hair out for hours trying to figure out where I slipped up:

I build and launch homepwner, hit the + to add a random item; it crashes with :

  • (void)setItemName:(NSString *)str
    {
    self.itemName = str; // **** hangs here Thread 1 BAD_ACCESS_CODE 2
    }
  • (instancetype)randomItem
    {
    // Create an immutable array of three adjectives
    NSArray *randomAdjectiveList = @[@“Fluffy”, @“Rusty”, @“Shiny”];

    // Create an immutable array of three nouns
    NSArray *randomNounList = @[@“Bear”, @“Spork”, @“Mac”];

    // Get the index of a random adjective/noun from the lists
    // Note: The % operator, called the modulo operator, gives
    // you the remainder. So adjectiveIndex is a random number
    // from 0 to 2 inclusive.
    NSInteger adjectiveIndex = rand() % [randomAdjectiveList count];
    NSInteger nounIndex = rand() % [randomNounList count];

    // Note that NSInteger is not an object, but a type definition
    // for “long”

    NSString *randomName = [NSString stringWithFormat:@"%@ %@",
    randomAdjectiveList[adjectiveIndex],
    randomNounList[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];
    NSLog(@“random Item generated %@”,randomName); // PRINTS RUSTY SPORK
    MHEItem *newItem = [[self alloc] initWithItemName:randomName // **** hangs here Thread 1 BAD_ACCESS_CODE 2
    valueInDollars:randomValue
    serialNumber:randomSerialNumber];

    return newItem;
    }

  • (instancetype)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
    if (!name) {
    NSLog(@“name is nil”); //does not print or breakpoint
    }
    self.itemName = name;
    self.serialNumber = sNumber;
    self.valueInDollars = value;
    self.dateCreated = [[NSDate alloc] init];

      // Create a NSUUID object - and get its string representation
      NSUUID *uuid = [[NSUUID alloc] init];
      NSString *key = [uuid UUIDString];
      _itemKey = key;
    

    }


#2

if I change the order of assignment to:

  • (instancetype)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
    if (!name) {
    NSLog(@“name is nil”);
    } else {
    NSLog(@“Name is %@”,name);
    }
    self.serialNumber = sNumber;
    self.valueInDollars = value;
    self.itemName = name;
    self.dateCreated = [[NSDate alloc] init];

      // Create a NSUUID object - and get its string representation
      NSUUID *uuid = [[NSUUID alloc] init];
      NSString *key = [uuid UUIDString];
      _itemKey = key;
    

    }

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

then it hangs when it hits self.serialNumber = sNumber;
so is self invalid? but that assignment is inside an if (self) block ???


#3

[quote]- (void)setItemName:(NSString *)str { self.itemName = str; // **** hangs here Thread 1 BAD_ACCESS_CODE 2 } [/quote]
That’s where the problem lies.

The property assignment statement is causing an infinite recursion, and consequently the program is running out of stack space.

In plain words, this is what is happening:

- (void)setItemName:(NSString *)str
{
    // "self.itemName = str" is equivalent to "[self setItemName:str]"!

    [self setItemName:str];
}

Write that method like this:

- (void)setItemName:(NSString *)str
{
    _itemName = [str mutableCopy];
}

[Become a competent programmer: pretty-function.org]


#4

Thanks, that does seem like my problem!