web-dev-qa-db-fra.com

tenter d'insérer un objet nul à partir d'objets [0]?

Dans mon application, j'ai une UITableView et quelques boutons sur lesquels l'utilisateur peut cliquer pour trier le tableau dans l'ordre en fonction de certains NSDate ou ints. Voici donc ma méthode pour essayer de trier mon UITableView:

- (void)sortStats:(id)sender reloadData:(BOOL)dataBool {
    NSSortDescriptor *descriptor = nil;
    UIButton *clickedButton = (UIButton*)sender;
    if (clickedButton.tag == 1) {
            descriptor = [NSSortDescriptor sortDescriptorWithKey:@"Date" ascending:NO];
    }
    [self.cellArray sortUsingDescriptors:[NSArray arrayWithObject:descriptor]];
    [[NSUserDefaults standardUserDefaults] setObject:self.cellArray forKey:@"cellArray"];
    if (dataBool) {
        [ivstatstableView reloadData];
    }
    [ivstatstableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];
}

Donc à l'origine, je venais d'avoir cette méthode sans le paramètre reloadData car il semblait que reloadData sur UITableView provoquait le crash.

Voici le journal des plantages de la console:

Arrêt de l'application en raison d'une exception non interceptée 'NSInvalidArgumentException', raison: '*** - [__ NSPlaceholderArray initWithObjects: count:]: tentative d'insertion d'un objet nul à partir des objets [0]'

Quoi qu'il en soit, y a-t-il un code ici qui pourrait provoquer ce crash? Je veux vraiment que cette fonctionnalité fonctionne dans mon application et je sais que je suis sur le point de la corriger, mais je ne suis pas sûr de la cause de ce problème.

Des idées?

21
SimplyKiwi

Il y a au moins un endroit où cela pourrait se produire, et peut-être d'autres. Dans le code où vous obtenez le contenu des valeurs par défaut de l'utilisateur, vous ne recherchez pas nil. Donc au lieu de ça:

[self.cellArray addObjectsFromArray:[[NSUserDefaults standardUserDefaults] objectForKey:@"array"]];

vous voudrez peut-être essayer ceci:

NSArray *defaultCellArray = [[NSUserDefaults standardUserDefaults] objectForKey:@"array"];
if (defaultCellArray) {
    [self.cellArray addObjectsFromArray:defaultCellArray];
}

Il est également possible que l'appel initWithObjects qui échoue (selon votre message d'erreur) soit imbriqué dans un autre appel, peut-être dans cet appel:

[self.cellArray sortUsingDescriptors:[NSArray arrayWithObject:descriptor]];

Si vous regardez la pile d'appels complète, elle vous dira si cet appel effectue des appels ultérieurs à initWithObjects et éventuellement en lui passant un nil. Dans votre cas, par exemple, vous devez passer un nil yo le tableau que vous créez si clickedButton.tag n'a pas encore été défini sur une valeur de 1 ou 2. Vous souhaiterez peut-être ajouter une clause else supplémentaire pour aider à diagnostiquer le problème:

if (clickedButton.tag == 1) {
        descriptor = [NSSortDescriptor sortDescriptorWithKey:@"Date" ascending:NO];
} else if (clickedButton.tag == 2) {
        descriptor = [NSSortDescriptor sortDescriptorWithKey:@"Score" ascending:NO];
} else {
    NSLog(@"Unexpected error: Can't determine sort descriptor");
}
11
Tim Dean

Tout cela est assez compliqué, mais une chose ressort:

[[NSUserDefaults standardUserDefaults] setObject:self.cellArray 
                                          forKey:@"cellArray"];

Je pense que vous devriez changer cela en ceci:

NSArray *array = [NSArray arrayWithArray:self.cellArray];
[[NSUserDefaults standardUserDefaults] setObject:array forKey:@"cellArray"];

Deuxièmement, ajoutez asserts () après chaque endroit où vous pensez que vous devriez avoir un objet, à savoir:

UIButton *theButton = ...
assert(theButton);

Vous dites également que le nombre de lignes est le double du nombre cellArray, devinez intentionnel.

2
David H