2010-09-04 3 views
0

Je ne sais pas comment décrire cela comme étant nouveau avec tous les développeurs et je suis vraiment impatient d'avoir une réponse de votre part. Je sais que vous pouvez être très occupé, mais s'il vous plaît essayez de m'aider!Chargement de la base de données au démarrage ralentit l'application

Voilà. J'ai une application qui charge une très grande base de données (bien qu'elle ne possède que 100 entrées, elle contient des images HiRes (100MB)). Au démarrage, une tableview présente les rangées -records (en utilisant seulement 3 attributs de la base de données). Cependant, il semble que la base de données WHOLE (y compris les images) est chargée au démarrage! Y a-t-il un moyen de ne charger que les 3 attributs (quelque chose comme "select") lorsque l'application démarre, puis lorsque l'utilisateur passe à didselectrowatindexpath charger le reste de l'enregistrement?

Parce que je n'ai aucune idée où regarder ou quoi faire j'apprécierais de l'aide de codage!

ici est le code im en utilisant:

#pragma mark - 
#pragma mark App support 

- (NSFetchedResultsController *)resetFetchedResultsController:(NSPredicate *)predicate cached:(BOOL)cached 
{ 

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Records" inManagedObjectContext:managedObjectContext]; 
    [fetchRequest setEntity:entity]; 


    NSSortDescriptor *partDescriptor = [[NSSortDescriptor alloc] initWithKey:@"displayOrder" ascending:YES]; 
    NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES]; 
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects: partDescriptor, nameDescriptor, nil]; 
    [fetchRequest setSortDescriptors:sortDescriptors]; 


    if (predicate != nil) 
     [fetchRequest setPredicate:predicate]; 

    NSString *cacheName = nil; 
    if (cached) 
     cacheName = @"Root"; 

    NSFetchedResultsController *aFetchedResultsController = [[[NSFetchedResultsController alloc] 
                   initWithFetchRequest:fetchRequest 
                   managedObjectContext:managedObjectContext 
                   sectionNameKeyPath:nil 
                   cacheName:cacheName] autorelease]; 
    aFetchedResultsController.delegate = self; 

    [fetchRequest release]; 
    [partDescriptor release]; 
    [nameDescriptor release]; 
    [sortDescriptors release]; 

    NSError *error = nil; 
    if (![aFetchedResultsController performFetch:&error]) { 
     // Handle error 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     exit(-1); // Fail 
    } 

    return aFetchedResultsController; 
} 







- (void)showRecords:(Records *)records animated:(BOOL)animated { 
    . 
    RecordsDetailViewController *detailViewController = [[RecordsDetailViewController alloc] initWithStyle:UITableViewStyleGrouped]; 
    detailViewController.records = records; 

    [self.navigationController pushViewController:detailViewController animated:animated]; 
    [detailViewController release]; 
} 


#pragma mark - 
#pragma mark Table view methods 


- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    cell.backgroundColor = [UIColor lightGrayColor]; 
} 



- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
    NSInteger count = [[fetchedResultsController sections] count]; 

    if (count == 0) { 
     count = 1; 
    } 

    return count; 
} 


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    NSInteger numberOfRows = 0; 

    if ([[fetchedResultsController sections] count] > 0) { 
     id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section]; 
     numberOfRows = [sectionInfo numberOfObjects]; 
    } 

    return numberOfRows; 
} 


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    static NSString *RecordCellIdentifier = @"RecordCellIdentifier"; 

    RecordTableViewCell *recordCell = (RecordTableViewCell *)[tableView dequeueReusableCellWithIdentifier:RecordCellIdentifier]; 
    if (recordCell == nil) { 
     recordCell = [[[RecordTableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:RecordCellIdentifier] autorelease]; 
     recordCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 
    } 

    [self configureCell:recordCell atIndexPath:indexPath]; 

    return recordCell; 
} 


- (void)configureCell:(RecordTableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath { 
    // Configure the cell 
    Records *records = (Records *)[fetchedResultsController objectAtIndexPath:indexPath]; 
    cell.records = records; 
} 



- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    if (self.searchDisplayController.isActive) 
     [self.tableView reloadData]; 


    Records *records = (Records *)[fetchedResultsController objectAtIndexPath:indexPath]; 

    [self showRecords:records animated:YES]; 
} 

// ceci est du RecordTableViewCell.m pour vous montrer les attributs im en utilisant:

#pragma mark - 
#pragma mark Record set accessor 

- (void)setRecord:(Record *)newRecord { 
    if (newRecord != record) { 
     [record release]; 
     record = [newRecord retain]; 
    } 
    imageView.image = [UIImage imageNamed:@"icon.png"]; 
    nameLabel.text = record.name; 
    overviewLabel.text = record.overview; 
    partLabel.text = record.part; 
} 

merci encore ...

+0

SQLite lui-même est très heureux de charger une base de données un peu à la fois, ne mettant que les choses en mémoire strictement nécessaire. Le problème est (presque certainement) dans la couche au-dessus de lui; Je sais qu'il doit y avoir une telle couche parce que vous n'écrivez pas directement le SQL là ... –

Répondre

0

Je voudrais séparer le grand fichier des métadonnées, parce que j'aime avoir la liberté de gérer ces ressources coûteuses séparément. Ensuite, je pourrais les stocker différemment, par exemple un système de fichiers ou un serveur http. Cela me permet de les mettre en cache ou de les envoyer à des emplacements distants de manière proactive pour réduire les temps de téléchargement. Le reste de la table peut alors contenir moins de blocs dans la base de données, ce qui nécessite moins d'accès au disque. De nombreuses bases de données font de toute façon interne, par exemple postgresql

Vous pouvez juste se référer à la ressource lourde par Id

+0

donc il n'y a aucun moyen de simplement charger certains attributs d'une entité dans une base de données au lieu de charger le tout au démarrage? – treasure

0

Ok ici il va. J'ai abandonné l'idée de charger séparément les attributs dont j'ai besoin au démarrage. Ce que j'ai fait ET QUI FONCTIONNE MAINTENANT PARFAITEMENT est de créer des RELATIONS dans mon modèle. Les images ne sont en cours de chargement que lorsqu'elles sont appelées!

Cette solution était dans mon esprit mais parce que j'avais déjà peuplé ma base de données il m'était difficile de répéter cette étape.

Cependant, je suis heureux que je l'ai fait!

maintenant ça marche comme il se doit !!

Heureux développeur !!

Questions connexes