0

All examples I find on shuffling arrays are for NSMutableArrays. Copying an NSArray to an NSMutable array, shuffling, then copying back always crashes the application. Is it even possible to shuffle an NSArray?

Anything in objective-c similar to Collections.shuffle() (Java)?

Edit

static NSUInteger random_below(NSUInteger n) {
NSUInteger m = 1;

do {
    m <<= 1;
} while(m < n);

NSUInteger ret;

do {
    ret = random() % m;
} while(ret >= n);

return ret;
}
- (NSArray *)loadAllData{
    XYZAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];

    NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext;
    NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Quote" inManagedObjectContext:managedObjectContext]; 
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"id" ascending:YES];  
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];   

    [request setSortDescriptors:sortDescriptors];
    [request setEntity: entity]; 

    NSError *myError;   
    NSArray *theResults = [managedObjectContext executeFetchRequest:request error:&myError];

    if (theResults == nil) {
        NSLog(@"Testing: No results found");
    }else {
        NSLog(@"Testing: Results found.");
    }

    [request release];
    [sortDescriptors release];

    for(NSUInteger i = [theResults count]; i > 1; i--) {
        NSUInteger j = random_below(i);
        [theResults exchangeObjectAtIndex:i-1 withObjectAtIndex:j];
    }

    return theResults;
}




warning: 'NSArray' may not respond to '-exchangeObjectAtIndex:withObjectAtIndex:' which crashed the application.     

error: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[_PFArray exchangeObjectAtIndex:withObjectAtIndex:]: unrecognized selector sent to instance 0x3d35a40
Oh Danny Boy
  • 4,857
  • 8
  • 56
  • 88
  • possible duplicate of [canonical way to randomize an NSArray in Objective C](http://stackoverflow.com/questions/791232/canonical-way-to-randomize-an-nsarray-in-objective-c) – Daniel DiPaolo Jun 07 '10 at 19:45
  • I had came across that post in my search. I tried the algorithm in the answer with the checkmark. I always got the warning and error above. – Oh Danny Boy Jun 07 '10 at 19:53

1 Answers1

2

OK. I think I see a problem. Always look at the error message. I thought you said that you were using NSMutableArrays in this function?

NSArray *theResults = [managedObjectContext executeFetchRequest:request error:&myError];

Change that to

NSMutableArray *theResults = [[managedObjectContext executeFetchRequest:request error:&myError] mutableCopy];

Tell me if it works, and if it doesn't, I'll try and help.

Some more info:

-exchangeObjectAtIndex:withObjectAtIndex:

is a method for a NSMutableArray. You were using a NSArray, they're different classes (NSMutableArray is a subclass (and adds methods that mean you can modify it) of NSArray).

Tom H
  • 1,316
  • 14
  • 26
  • I get the data from a SQLite database. I can display all data consecutively without any app crashes. The elements returned are in a NSArray. But when I try any of the NSMutableArray shuffles I see on the internet, the app crashes. I just want to shuffle the NSArray is all. – Oh Danny Boy Jun 07 '10 at 19:48
  • Can you edit your post, adding in the shuffling code and how you're using it? That would likely help? It is impossible to shuffle an NSArray, without creating a mutable array from it somehow. So a good thing would be to paste some code and let us help you debug it. – Tom H Jun 07 '10 at 19:50
  • It occurred to me to use NSMutableArray, however, I always got this error warning: incompatible Objective-C types initializing 'struct NSArray *', expected 'struct NSMutableArray *'which even after researching I do not completely understand. – Oh Danny Boy Jun 07 '10 at 20:25
  • Did you try that with the code I suggested? The mutableCopy method might make the difference, because [managedObjectContext executeFetchRequest:request error:&myError] returns an NSArray, not a NSMutableArray. So then you would have had a pointer to an NSArray inside a thing that looked to you and the compiler like a NSMutableArray. I don't think I'm making much sense though, so please tell me... – Tom H Jun 07 '10 at 20:33
  • Sorry, you are right, I forgot to add "mutableCopy" at the end of it. Wow, thanks. – Oh Danny Boy Jun 07 '10 at 20:37
  • No problem... I thought that might be the problem! :) – Tom H Jun 07 '10 at 20:39