2

I'm a total noob and need help with a method I'm writing.

The method creates a deck of cards (using NSMutableArray). I'm first experimenting with loading the array with numbers 1-13 randomly (each number appearing once).

When I run a simple test program to print the values in the array, I get a "Build Successful" but an error once the program starts. The error says "[__NSArrayM insertObject:atIndex:]: object cannot be nil".

Once I understand what I'm doing wrong, I can then expand on the method properly. Thanks!

NB: This is my first post. Is this type of question ok?

- (void) createDeck {

int r;
BOOL same;
deck = [[NSMutableArray  alloc]init];
NSNumber *randNum;// = nil;

randNum = [[NSNumber alloc]init];

[randNum  initWithInt: (arc4random()%13)+1];
[deck  addObject: randNum];          // First card added to deck

same = FALSE;

while (!same) {

    for (int i=1; i<13; i++) {

        same = FALSE;

        for (r=0; r<=i; r++) {

            [randNum  initWithInt: (arc4random()%13)+1];

            if ([deck  objectAtIndex:r] == [deck  objectAtIndex:i]) {

                same = TRUE;

            }

            [deck addObject: randNum];           // Next card added to deck

        }

    }
}

}

Nicholas Shanks
  • 10,623
  • 4
  • 56
  • 80
Fred
  • 41
  • 5
  • initWithInt returns an NSNumber, it doesn't populate your variable. Change both instances of [randNum initWithInt: (...)] to randNum = [randNum initWithInt: (...)] – Rey Gonzales Aug 01 '13 at 15:43
  • Tried what you suggested. Didn't work. Thanks though :) – Fred Aug 01 '13 at 16:16
  • 1
    @Fred .. this is a not a solution, but a comment about your approach. Rather than trying to add random numbers to your array you are better off adding all the numbers one after the other and then shuffling the contents of the array around. There are plenty of solutions of you google how to shuffle an NSArray. My fav is this one: http://stackoverflow.com/questions/56648/whats-the-best-way-to-shuffle-an-nsmutablearray/10874468#10874468 which adds a `shuffle` method to NSArray that you can use all over the place – Peter M Aug 01 '13 at 18:04

2 Answers2

3

you cannot re-init randNum:

NSNumber *randNum;// = nil;

randNum = [[NSNumber alloc]init];

[randNum  initWithInt: (arc4random()%13)+1];

and the third line is missing the assignment anyway. just do:

NSNumber *randNum = [[NSNumber alloc] initWithInt:(arc4random()%13)+1];

and put that inside the inner for loop, like this:

BOOL same = FALSE;
NSMutableArray *deck = [[NSMutableArray  alloc] initWithCapacity:13];

[deck addObject:[[NSNumber alloc] initWithInt:(arc4random()%13)+1]]; // First card added to deck
while (!same) {
  for (int i = 1; i < 13; i++) {
    same = FALSE;
    for (int r = 0; r <= i; r++) {
        NSNumber *randNum = [randNum initWithInt:(arc4random()%13)+1]; // modern ObjC will assign a register for this outside the while loop, but restrict the variable's scope to the inner-most loop
        if ([deck objectAtIndex:r] == [deck objectAtIndex:i])
            same = TRUE;
        [deck addObject: randNum]; // Next card added to deck
    }
}

Note that I haven't thought through the logic of what you are trying to do here, I've only attempted to resolve the NULL object reference. The error was referring to the first line [deck addObject: randNum] outside of the loop.

Nicholas Shanks
  • 10,623
  • 4
  • 56
  • 80
  • Thanks for the quick reply, Nicholas. I added what you mentioned in the inner for loop. Also removed the randNum = [[NSNumber alloc]init]. It still doesn't work. Is it possible to show the actual change in the submitted code? Thanks! – Fred Aug 01 '13 at 16:15
  • Keep in mind that NSNumber is an object and that using == compares the actual objects themselves. This may or may not be what you are looking for. If you want to compare object values, you should either compare the `intValue` or use `isEqualToNumber:` – mrosales Aug 01 '13 at 17:38
  • @mros This is true, but in the case of NSNumbers, like NSStrings, two objects containing the same value share the same memory address, and are just refCounted by the framework. – Nicholas Shanks Aug 01 '13 at 19:53
0

Try to use this line of code where you using NSNumber

NSNumber * randNum = [NSNumber numberWithInt: (arc4random%13)+1];

Instead of

[[NSNumber alloc] initWithInt: ]
Sahil Mahajan
  • 3,922
  • 2
  • 29
  • 43