2009-07-22 8 views
4

Ich schreibe eine Coredata basierte iPhone App, die Rezepte anzeigt. Um die Leistung zu verbessern, wenn ich sie in einer TableView anzeigen möchte, möchte ich die Stapelverarbeitung aktivieren (-setFetchBatchSize :) und nur das Attribut "name" abrufen (-setPropertiesToFetch :). Wenn ich beides einschalte, funktioniert es nicht und die Liste ist leer. Sobald ich eine der im folgenden Code markierten Zeilen auskommentiere, funktioniert es einwandfrei.Coredata auf iPhone, setFetchBatchSize & setPropertiesToFetch in einer Anfrage

Was fehlt mir hier? Ist es unmöglich, beides zu haben?

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"]]]; 

Antwort

0

Update: "NSUnderlyingException = Die Datenbank beschädigt erscheint (ungültige Primärschlüssel)," Wenn ich nach

den Fehler NSLog
[fetchedResultsController performFetch:&error]; 

ich. Aber ich weiß nicht, was das bedeutet und was es mit der Aktivierung beider Methoden zu tun hat.

2

Sieht so aus, als ob Sie einen Fehler in CoreData gefunden haben. Sie können das sicher überprüfen, indem Sie die SQL-Protokollierung aktivieren. Ich schätze, dass das Aktivieren beider Optionen leicht ungültiges SQL generiert.

Die Option, die Sie verwenden möchten, ist "com.apple.CoreData.SQLDebug 1" - Sie können dies über die Befehlszeile angeben oder die Standardeinstellung für Ihr Programm festlegen.

-Wil

+0

Das CoreData-Debugframework funktioniert nur auf dem Desktop, nein? Ich dachte nicht, dass es eine iPhone-Version des Debug-Frameworks gibt. – Hunter

+0

Ich spreche nicht über Debug-Frameworks. Ich sage, setze eine Umgebungsvariable oder einen Standard, um eine zusätzliche Protokollierung im normalen CoreData-Framework auszulösen. –

+0

Wil, hast du das eigentlich am Telefon arbeiten lassen? Ich hatte kein Glück, und diese Person schlägt vor, dass es ein bekannter Fehler ist: http://stackoverflow.com/questions/822906/how-do-i-get-the-coredata-debug-argument-to-output-to -the-console –

0

Hunter können Sie com.apple.CoreData.SQLDebug 1 am Telefon verwenden, aber der Simulator

+0

Sie sollten Kommentare nicht als Antworten, schlechter Stil tarnen. – Till

4

Ich bin weit von einem Kerndaten Experten nicht, aber ich habe diese erfolgreich zu arbeiten in meiner Situation. Ich denke, dass der "Konflikt" zwischen setFetchBatchSize und setPropertiesToFetch eher ein Nebeneffekt davon ist, wie Kerndaten funktionieren und kein Fehler per se.

In meinem Fall habe ich zwei Abrufe. In der ersten Version wurde der Ergebnistyp auf NSManagedObjectResultType festgelegt, und mit setFetchBatchSize wurde die Menge der aktiv in den Speicher gebrachten Daten begrenzt. Beim zweiten Fetch befülle ich ein Array von Titeln basierend auf einem einzelnen Attribut und setze den Ergebnistyp auf NSDictionaryResultType und fetchBatchSize auf 0 (unendlich).

Basierend auf Tests funktioniert dieses Szenario einwandfrei. Alle Datensätze im initialen Abruf (mit den tatsächlichen managedObjects) sind fehlerhaft und durch fetchBatchSize speicherbegrenzt. Der zweite Abruf gibt ein einfaches Wörterbuch von Titeln zurück. Dies erfordert viel weniger Speicher als das Durchlaufen aller tatsächlichen managedObjects, um auf das Titelattribut zuzugreifen. Es ist sinnvoll, dass beim zweiten Abruf fetchBatchSize deaktiviert ist, da das vollständig bestückte Wörterbuch als einzelnes Ergebnis zurückgegeben wird und die Stapelverarbeitung nicht geeignet ist.

Ich bin mir nicht sicher, ob ich hier 100% klar bin (Kerndaten-Terminologie ist ein bisschen geheimnisvoll ...), aber unter dem Strich denke ich, dass alles so funktioniert wie beabsichtigt.

+0

+1 Diese Antwort ist sinnvoll.Die 'setPropertiesToFetch:' Methode tut nichts, wenn der Ergebnistyp NSDictionaryResultType ist (dies wird in der Antwort erwähnt, aber nicht explizit angegeben). Ich gehe davon aus, dass der Code zu funktionieren schien, wenn 'setFetchBatchSize:' auskommentiert wurde, weil die verwalteten Objekte abgerufen wurden und nicht nur die gewünschten Eigenschaften. – yabada

+0

Ein lustiger Hinweis: Wenn Sie die Dokumentation für 'setPropertiesToFetch:' in der NSFetchRequest-Klassenreferenz lesen, sieht es so aus, als ob jemand wahrscheinlich einen Fehler gepostet hätte und ihr Kommentar versehentlich (?) In den Abschnitt "Diskussion" geschafft hat. Die Person wird vorgeschlagen, dass in der Dokumentation angegeben wird, dass der Wert nur verwendet wird, wenn 'resultType' auf NSDictionaryResultType gesetzt ist, weil er/sie "gerade eine Stunde verloren hat, weil er denkt, dass er auf Ergebnistypen von verwalteten Objekten angewendet wird." Komisch! – yabada