2009-01-28 7 views
1

J'ai une application I phone qui, à l'ouverture, doit afficher une table de données contenant environ 25 000 enregistrements. Chaque enregistrement comprend deux champs: TITLE et DESCRIPTION. Les deux champs sont visibles dans chaque cellule de tableau. La tableview est également entièrement consultable avec un UISearchBar. Lorsque l'application démarre et que cette vue est chargée, un "objet de collection" récupère toutes les données de la table et les charge dans "objets objet". Comme j'ai besoin de deux champs de recherche, je n'ai vraiment rien à hydrater/déshydrater; ainsi, la table complète est en mémoire. Il doit y avoir une meilleure façon d'offrir la capacité de recherche complète, mais réduire considérablement le nombre d'objets en mémoire à la fois.Conception de volumes élevés de données dans une application iPhone

Des idées?

EDIT:

Je suppose que je devrais expliquer davantage.

J'utilise déjà une base de données SQLite. Mon problème est que cela prend trop de temps pour charger 20 000 enregistrements en mémoire et que l'application semble léthargique.

En outre, si je n'ai que 100 enregistrements de chaque côté de la sélection actuelle, comment puis-je rechercher TOUS les enregistrements (y compris ceux qui ne sont pas en mémoire)?

Je vais regarder dans la suggestion de délégué de table.

Répondre

1

Vous devez essayer d'utiliser un délégué pour votre table et charger uniquement les éléments en mémoire à la demande. Si seulement les dix premiers éléments sont affichés, le système d'exploitation vous les demandera seulement.

Vous devez également envisager de stocker vos enregistrements dans une base de données SQLite. Lorsqu'une recherche est active, le délégué utilisera la requête SQL générée en utilisant le terme de recherche actuel.

0

Il peut être judicieux de rechercher et de conserver en mémoire 50 à 200 ou plus avant/après l'écran en cours afin de pouvoir faire défiler les éléments à mesure qu'ils se chargent plus de la base de données.

modifier; SQL lite est aussi une excellente idée comme mentionné ci-dessus.

2

Je repenserais l'architecture de votre application.

Vous devez vous rappeler, l'iPhone n'est pas la même chose qu'une application de bureau, et les gens n'utilisent pas leurs téléphones comme ils le font sur un ordinateur ordinaire. L'iPhone est utilisé pour des minutes à la fois, pas des heures. Personne ne voudra jamais faire défiler plus de 20 000 entrées. Pour être honnête, je ne suis pas sûr que quelqu'un voudrait le faire dans une application de bureau. À la place, chargez un nombre limité d'entrées, peut-être 100 ou 200 tops. Puis laissez l'utilisateur charger plus (ou chercher ce dont ils ont besoin).

+0

Bon ... c'est pourquoi je pose la question ... L'utilisateur devra cependant être capable de défiler de façon transparente. Comment puis-je mettre en page des objets dans et hors de la mémoire lorsque l'utilisateur défile? C'est le coeur de mon problème. – radesix

3

Vous devriez utiliser SQL pour chercher plutôt que de tout charger dans la mémoire et de chercher à partir de là. À quoi sert une base de données si vous l'utilisez comme un fichier plat?

De plus, beaucoup d'applications ont une entrée "charger plus" comme dernière entrée de leur vue de table qui ajoute plus d'éléments à la vue.

2

Peut-être que je peux clarifier ce que dit le reste du groupe.

Comme vous le savez sûrement vue de table doit avoir une source de données qui met en œuvre au moins les deux méthodes requises dans le protocole <UITableViewDatasource>:

– tableView:cellForRowAtIndexPath: 
– tableView:numberOfRowsInSection: 

Je pense que votre implémentation actuelle de – tableView:cellForRowAtIndexPath: saisit juste les deux cordes de votre objet de collection global, les place dans une cellule (j'espère que celui qui est réutilisé correctement!) et le renvoie.

Ce qu'il devrait probablement faire est de récupérer ces données de la base de données au besoin. Je mettrais en œuvre une classe (ou des classes) pour servir de médiateur entre l'application et la base de données et renvoyer des blocs, par ex. 100 lignes à la fois, quelle que soit la classe qui joue le rôle de source de données (SQLite supporte les mots-clés LIMIT et OFFSET), qui ne retiendront que cet ensemble limité. Lorsque – tableView:cellForRowAtIndexPath: est appelé par la tableView, vous pouvez vérifier si les données sont dans le bloc stocké localement (je ferais une propriété pour stocker le décalage d'enregistrement actuel) et si ce n'est pas le cas, mettez à jour le bloc local avec une requête au DB pour le prochain (ou précédent, selon le cas) 100 enregistrements.

Presto. Un nombre fixe (100) d'enregistrements sont en mémoire à un moment donné, la source de données fournit des données à la vue de table selon les besoins. Vous pourriez obtenir plus chic, mais c'est l'idée générale.

En ce qui concerne la recherche, en supposant que vous faites une recherche de texte libre sur le titre, juste avoir la base de données question de médiateur quelque chose comme

'select id, title, description from yourTable where title like ?' 

et lier la? à tout ce que l'utilisateur a tapé, avec des caractères génériques dans les endroits appropriés (ne pas oublier de désinfecter votre entrée ... pas que quelqu'un est très susceptible d'effectuer une injection SQL sur votre application iPhone, mais, les habitudes et tout ... :)

Évidemment, si vous recherchez simplement au lieu de filtrer les résultats, vous devrez tout ajuster un peu, mais j'espère que c'est un début.

Bonne chance!

Questions connexes