2010-08-25 5 views
0

Je reçois un plantage étrange lorsque j'essaie de sauvegarder mon modèle. Voici mon code:Plantage étrange lors de la sauvegarde de managedObjectContext

TJModel *model = [TJModel sharedTJModel]; 
NSFetchRequest *request = [[[NSFetchRequest alloc] init]autorelease]; 
[request setReturnsObjectsAsFaults:NO]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"TJVideoList"inManagedObjectContext:[model managedObjectContext]]; 
[request setEntity:entity]; 

NSError *error = nil; 
NSMutableArray *mutableFetchResults = [[[model managedObjectContext] executeFetchRequest:request error:&error] mutableCopy]; 

if (error != nil) 
    NSLog(@"error %@",[error localizedDescription]); 


TJVideoList *videoList = nil; 

if ([mutableFetchResults count] == 0) { 

    videoList = (VideoList *)[NSEntityDescription insertNewObjectForEntityForName:@"TJVideoList" 
       inManagedObjectContext:[model managedObjectContext]]; 
} 
else 
{ 
    videoList = [mutableFetchResults objectAtIndex:0]; 
} 


[videoList addVideoListObject:recordedVideo]; 
error = nil; 

if (![[model managedObjectContext] save:&error]) { 

Et accident ..... C'est ce que dit dans le terminal:

-[NSConcreteValue UTF8String]: unrecognized selector sent to instance 0x1d33f0 

Je pensais que ce pourrait être un cuestion d'objets désallouées, alors je les ai retenu comme ceci:

[managedObjectContext setRetainsRegisteredObjects:YES]; 

Sans chance.

+0

Sur quelle ligne se bloque-t-il, 'save:'? – TechZen

Répondre

1

Votre panne n'est pas un résultat de ce code.

Les blocages dans les sauvegardes résultent généralement d'une erreur avec les attributs d'un managedObject. Dans ce cas, vous avez affecté quelque part la mauvaise valeur à un attribut de chaîne. Lorsque le contexte convertit l'attribut de chaîne en chaîne UTF8 pour la persistance, l'objet qui s'y trouve à la place de NSString ne comprend pas le message et les résultats de l'incident.

Bien que ce code devrait fonctionner bien, vous n'avez des pratiques risquées:

NSFetchRequest *request = [[[NSFetchRequest alloc] init]autorelease]; 

C'est une mauvaise pratique. autorelease est la même que la version. Vous ne devriez pas l'envoyer à un objet tant que vous n'en avez pas terminé avec lui. autorelease marque un objet pour la mort la prochaine fois que le pool de mémoire est drainé. Dans certains cas, cela va tuer l'objet de façon inattendue. Même si cela ne causera pas de problèmes ici, vous ne voulez pas prendre l'habitude de prendre ce raccourci parce qu'il finira par vous mordre.

Vous ne devez utiliser autorelease lorsque la portée actuelle se fait avec l'objet, mais l'objet est envoyé en dehors du champ d'application (habituellement dans un retour de la méthode.)

NSMutableArray *mutableFetchResults = [[[model managedObjectContext] executeFetchRequest:request error:&error] mutableCopy]; 

Le tableau mutable ici est inutile tout comme la copie. C'est apparemment dans quelque matériel de référence quelque part parce qu'il ne cesse d'élever le code des novices au cours des derniers mois. Si vous n'allez pas modifier un tableau, il n'y a aucune raison de le rendre modifiable. Dans le cas d'un tableau d'objets gérés, il est inutile de copier le tableau.

videoList = [mutableFetchResults objectAtIndex:0] 

Puisque vous avez aucun descripteur de tri pour la récupération, le tableau mutableFetchResults sera dans un ordre aléatoire. Si vous renvoyez plus d'un objet, ce qui est presque toujours le cas, vous obtiendrez un objet aléatoire TJVideoList à l'élément zéro chaque fois que vous exécutez le code.

+0

btw que indésirable '-mutableCopy' est dans un exemple Apple. J'ai déposé un radar contre. Il figure également dans le livre de développement Head Start iPhone (copié à partir de la documentation Apple). –

+0

Merci beaucoup à tous pour vos informations et surtout les suggestions, elles sont inestimables. Et comme Marcus l'a remarqué, j'ai pris le code d'un exemple d'Apple. Tout ce qui brille n'est pas d'or! – toupper

+0

@Marcus S. Zarra - Ah, ha! Maintenant que nous avons trouvé le repaire des vampires, nous pouvons faire un pieu dans son cœur! – TechZen

1

Cela ressemble plus à une instance NSValue (NSNumber, très probablement, car il s'agit de la sous-classe la plus couramment utilisée) où un NSString était attendu. Le -retainsRegisteredObjects: est peu probable d'être nécessaire (il ne résoudra pas un problème lié à la mémoire de toute façon).

Il peut également s'agir d'un problème de version excessive. Essayez de courir avec la détection Zombie activée (voir le menu Exécuter).

Questions connexes