2009-07-22 6 views
4

J'écris une application iPhone basée sur Coredata qui affiche des recettes. Pour améliorer les performances, lorsque vous les affichez dans un TableView, je veux activer le traitement par lots (-setFetchBatchSize :) et récupérer uniquement l'attribut "name" (-setPropertiesToFetch :). Lorsque j'allume les deux, cela ne fonctionne pas et la liste est vide. Dès que je commente l'une des lignes marquées dans le code ci-dessous, cela fonctionne très bien.Coredata sur iPhone, setFetchBatchSize et setPropertiesToFetch en une seule demande

Qu'est-ce qui me manque ici? Est-ce impossible d'avoir les deux?

NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease]; 
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Rezept" inManagedObjectContext:chk_context]]; 
// *snip* 

//BATCHING 
[fetchRequest setFetchBatchSize:25]; 

NSDictionary *entityProperties = [[NSEntityDescription entityForName:@"Rezept" inManagedObjectContext:chk_context] propertiesByName]; 

//PROPERTIES 
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:[entityProperties objectForKey:@"name"]]]; 

Répondre

0

Mise à jour: "NSUnderlyingException = La base de données apparaît corrompue (clé primaire invalide);" Quand je NSLog l'erreur après

[fetchedResultsController performFetch:&error]; 

je reçois. Mais je ne sais pas ce que cela signifie et ce que cela a à voir avec l'activation des deux méthodes.

2

On dirait que vous avez trouvé un bug dans CoreData. Vous pouvez vérifier avec certitude en activant la journalisation SQL - Je suppose que l'activation des deux options génère un SQL légèrement invalide.

L'option que vous souhaitez utiliser est "com.apple.CoreData.SQLDebug 1" - vous pouvez spécifier ceci à partir de la ligne de commande, ou définir la valeur par défaut de votre programme.

-Wil

+0

La structure de débogage CoreData ne fonctionne que sur le bureau, non? Je ne pensais pas qu'il y avait une version iPhone des frameworks de débogage. – Hunter

+0

Je ne parle pas de framework de débogage. Je dis, définir une variable d'environnement ou une valeur par défaut pour déclencher la journalisation supplémentaire dans le cadre CoreData normal. –

+0

Wil, avez-vous réellement eu ce travail au téléphone? Je n'ai pas eu de chance, et cette personne suggère que c'est un bug connu: http://stackoverflow.com/questions/822906/how-do-i-get-the-coredata-debug-argument-to-output-to -la-console –

0

Hunter vous pouvez utiliser com.apple.CoreData.SQLDebug 1 sur le téléphone, mais pas en utilisant le simulateur

+0

Vous ne devriez pas déguiser les commentaires comme des réponses, un mauvais style. – Till

4

Je suis loin d'être un expert de données de base, mais je suis arrivé à travailler avec succès ce dans ma situation. Je pense que le "conflit" entre setFetchBatchSize et setPropertiesToFetch est plus un effet secondaire de la façon dont les données de base fonctionnent et pas un bogue en soi.

Dans mon cas, j'ai fait deux extractions. Dans le premier, le type de résultat a été défini sur NSManagedObjectResultType et j'ai utilisé setFetchBatchSize pour limiter la quantité de données activement mises en mémoire. Dans le second fetch, je remplis un tableau de titres basé sur un seul attribut et définit le type de résultat sur NSDictionaryResultType et fetchBatchSize sur 0 (infini). Basé sur des tests, ce scénario fonctionne parfaitement. Tous les enregistrements de l'extraction initiale (avec les managedObjects réels) sont faussés et limités en mémoire par fetchBatchSize. Le second fetch retourne un dictionnaire simple de titres. Cela prend beaucoup moins de mémoire que d'itérer dans tous les managedObjects actuels pour accéder à l'attribut title. Il est logique que le second fetch ait besoin de fetchBatchSize désactivé car il renvoie le dictionnaire entièrement rempli sous la forme d'un résultat unique et le traitement par lot ne serait pas approprié. Je ne suis pas sûr d'être 100% clair ici (la terminologie de base de données est un peu arcane ...) mais l'essentiel est que je pense que tout fonctionne comme prévu.

+0

+1 Cette réponse est logique.La méthode 'setPropertiesToFetch:' ne fait rien à moins que le type de résultat ne soit NSDictionaryResultType (ceci est fait dans la réponse mais pas explicitement). Je suppose que le code a semblé fonctionner quand 'setFetchBatchSize:' a été commenté parce que les objets gérés ont été récupérés et pas seulement les propriétés désirées. – yabada

+0

Une note amusante: si vous consultez la documentation de 'setPropertiesToFetch:' dans la référence de classe NSFetchRequest, il semble que quelqu'un ait probablement publié un bogue et que leur commentaire soit par inadvertance (?) Dans la section "discussion". La personne est suggérée que la documentation devrait indiquer que la valeur est seulement utilisée si 'resultType' est défini sur NSDictionaryResultType car il/elle" a juste perdu une heure en pensant qu'il s'appliquait aux types de résultats d'objets gérés. " Drôle! – yabada

Questions connexes