Silver Challenge + randomItem = errors


My solution for the silver challenge works, but when I try to use my new initialization method AND the randomItem method, I get an error. Since the individual parts work fine, clearly there’s some combination of the two that is causing the problem, but I really have no idea what the problem might be. Here’s my solution for the silver challenge:


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


- (id)initWithItemName:(NSString *)name serialNumber:(NSString *)sNumber
    return [self initWithItemName:name valueInDollars:0 serialNumber:sNumber];

And just for the sake of completeness, here’s the randomItem method, which should be just as it appears in the book:

+ (id)randomItem
    NSArray *randomAdjectiveList = [NSArray arrayWithObjects:@"Fluffy", @"Rusty", "@Shiny", nil];
    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;

Here’s the body of main.m:

        BNRItem *o = [[BNRItem alloc] initWithItemName:@"Valueless lump" serialNumber:@"923475843957"];
        NSLog(@"%@", o);
        NSMutableArray *items = [[NSMutableArray alloc] init];
        for (int i = 0; i < 10; i++)
            BNRItem *p = [BNRItem randomItem];
            [items addObject:p];
        for (int j = 0; j < [items count]; j++)
            BNRItem *item = [items objectAtIndex:j];
            NSLog(@"%@", item);
        items = nil;
        o = nil;

And last but not least, here’s what I get when I run that:

0x7fff91f82580:  testq  %rdi, %rdi
0x7fff91f82583:  je     0x7fff91f8259b            ; objc_msgSend_vtable5 + 27
0x7fff91f82585:  testl  $1, %edi
0x7fff91f8258b:  jne    0x7fff91f8259f            ; objc_msgSend_vtable5 + 31
0x7fff91f8258d:  movq   (%rdi), %rax
0x7fff91f82590:  movq   24(%rax), %rax
0x7fff91f82594:  movq   8(%rsi), %rsi
0x7fff91f82598:  jmpq   *40(%rax)
0x7fff91f8259b:  xorl   %eax, %eax
0x7fff91f8259d:  ret    
0x7fff91f8259e:  nop    
0x7fff91f8259f:  movl   %edi, %eax
0x7fff91f825a1:  andl   $15, %eax
0x7fff91f825a4:  leaq   1129373(%rip), %r10
0x7fff91f825ab:  movq   (%r10,%rax,8), %r10
0x7fff91f825af:  movq   24(%r10), %rax
0x7fff91f825b3:  movq   8(%rsi), %rsi
0x7fff91f825b7:  jmpq   *40(%rax)
0x7fff91f825ba:  nopw   (%rax,%rax)

The fourth last line is marked with an EXC_BAD_ACCESS error. In the randomItem method, this particular line is throwing the error:

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

Now, the weird thing (to me, anyway) is that in isolation, both randomItem and my new initialization method work just fine - if I comment out either one, the other does exactly what you would expect it to. If I comment out the call to initWithItemName in randomItem and just return an empty item, I still get the error, but at a different line in randomItem (this time, it’s the line that sets randomName).

But if I try to do both at the same time, I get this error.

Any ideas? I’m sure I’m missing something obvious, but I can’t see what that would be.

Thanks very much!


Nevermind, found my silly error, finally:

NSArray *randomAdjectiveList = [NSArray arrayWithObjects:@"Fluffy", @"Rusty", "@Shiny", nil];

That "@Shiny" should be @"Shiny"

On the one hand, it took me forever to spot that particular needle in the haystack. On the other hand, I’m that much less likely to make the same error again.

(I hope)