Advertise here




Advertise here

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In with Google Sign In with OpenID
Please do not post the same thing multiple times. The board software automatically flags certain posts as needing moderator attention. This happens the most often for new users. I'm pretty sure this is made clear at the time you attempt to post. Posting the same thing over and over again just makes that many more posts the moderators have to weed through later. This makes us sad. Don't make us sad. If your post/thread doesn't appear, just wait a while. Don't post it again. If it hasn't shown up by the next day, then you can try again. I normally go through posts in the mornings, and try to check a few times throughout the day, but I'm not here 24/7. There will typically be a significant delay before posts are approved. Just be patient.

TableView is not update from a NSFetchedResultsController

Hy,

I'm new in Core Data, I work in a tableView, witch visualizes the corresponding element one of my datatables.
A have some tables in my database, but now just two is important, the SONG and the COLLECTION tables, there is in relationship with each other. One of my class (RootViewColtroler) I want to alloc a SongTableViewControler (code is below) to visualize the SONGS in a specified COLLECTION:
When the app is running, I select a collection calling this function:

- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.songListView = nil;
COLLECTIONS *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath];
NSUInteger i = [selectedObject.collectionContainSongs count] ;
NSString * s = [NSString stringWithFormat: @\"%d\", i];
SongTableViewController* songView = [[SongTableViewController alloc] initWithNibName:@\"SongTableViewController\" songs:selectedObject.collectionContainSongs managedcont:managedObjectContext title:selectedObject.name bundle:nil];
self.songListView = songView;
[songView release];
[self.navigationController pushViewController:self.songListView animated:TRUE];
}


The header of my SongTableViewController class is the follow:

#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
@class RootViewController;
@interface SongTableViewController : UITableViewController <NSFetchedResultsControllerDelegate>{
NSFetchedResultsController *songfetchedResultsController;
NSManagedObjectContext *managedObjectContext;
UINavigationBar* navBar;
//@private:
NSPredicate *songPredicate;
//NSMutableArray* mysongs;
}
@property (nonatomic, retain) NSFetchedResultsController *songfetchedResultsController;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain) IBOutlet UINavigationBar* navBar;
@property (nonatomic, retain) NSMutableArray* mysongs;
@property (nonatomic, retain) NSPredicate *songPredicate;

- (id)initWithNibName:(NSString *)n songs:(NSSet*)s managedcont:(NSManagedObjectContext*) _managedObjectContext title:(NSString *)_title bundle:(NSBundle *)b;
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath ;
@end

The implementation file of my SongTableViewController class is the follow

#import \"SongTableViewController.h\"
#import \"SONGS.h\"

@implementation SongTableViewController
@synthesize navBar, mysongs, managedObjectContext, songfetchedResultsController, songPredicate;

- (id)initWithNibName:(NSString *)n songs:(NSSet*)s managedcont:(NSManagedObjectContext*) _managedObjectContext title:(NSString *)_title bundle:(NSBundle *)b
{
if(self = [super initWithNibName:n bundle:b])
{
self.managedObjectContext = _managedObjectContext;
self.title = _title;
}
return self;
}

- (void)viewDidLoad {
[super viewDidLoad];
NSError *error = nil;
//I want to create a predicate for chosen the corresponding songs in the COLLECTION. It works fine.
if (self.title != nil){
self.songPredicate = [NSPredicate predicateWithFormat: @\"(songBelongingToCollection.name LIKE[c] %@)\", self.title];
}
else{
self.songPredicate =nil;
}
if (![[self songfetchedResultsController] performFetch:&error]) {
NSLog(@\"Unresolved error %@, %@\", error, [error userInfo]);
abort();
}
}

- (void)viewWillDisappear:(BOOL)animated {
self.songfetchedResultsController = nil;
[super viewWillDisappear:animated];
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
SONGS *managedObject = [self.songfetchedResultsController objectAtIndexPath:indexPath];
NSLog(@\"The title of the song: %@\", managedObject.name);
[cell.textLabel setText : managedObject.name] ;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
NSLog([NSString stringWithFormat: @\"section :%d\", [[self.songfetchedResultsController sections] count]]);
return [[self.songfetchedResultsController sections] count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.songfetchedResultsController sections] objectAtIndex:section];
NSLog([NSString stringWithFormat: @\"rownum: %d\", [sectionInfo numberOfObjects]]);
return [sectionInfo numberOfObjects];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @\"Cell\";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}

//The most important function, I think, this is the source of the problem.
- (NSFetchedResultsController *)songfetchedResultsController {
if (songfetchedResultsController != nil) {
return songfetchedResultsController;
}
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@\"SONGS\" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Set the batch size to a suitable number.
[fetchRequest setFetchBatchSize:20];
if (self.songPredicate != nil) {//this part is always called, when the view is loaded, and it is valid.
NSLog(@\"predicate: %@\",self.songPredicate);
[fetchRequest setPredicate:self.songPredicate];
self.songPredicate = nil;
}
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@\"name\" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@\"Root\"];
aFetchedResultsController.delegate = self;
self.songfetchedResultsController = aFetchedResultsController;
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];
return songfetchedResultsController;
}

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {

switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;

case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
break;
}
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSManagedObject *objectToDelete = [self.songfetchedResultsController objectAtIndexPath:indexPath];
NSManagedObjectContext *context = [self.songfetchedResultsController managedObjectContext];
[context deleteObject:objectToDelete];
NSError *error;
if (![context save:&error]) {
NSLog(@\"Unresolved error %@, %@\", error, [error userInfo]);
abort();
}
}
}
- (void)dealloc {
[super dealloc];
self.songPredicate = nil;
self.songfetchedResultsController = nil;
}
@end


When I choose a COLLECTION at first time, the valis SONGS in the screen (in the rows of the table view). But choosing an other COLLECTION, the same SONGS at the screen... I think the fetchresultcontroller is always updated (leastwise the Predicate object is updated), but the view is not updated.

Help me, what is wrong of my code?
(the 'didReceiveMemoryWarning', function is deleted by the post caused the high number of characters...)
Thanks!
Post edited by ingaham on

Replies

Sign In or Register to comment.