NSFetchedResultsController seems to be inserting empty objects into array?

泄露秘密 提交于 2019-12-12 03:49:22

问题


I'm not sure what's going wrong. I have one Entity in my data model, called Quote, and around 3,000 of them stored in a .sqlite. I'm just trying to get one of the attributes of those entities into the cells of a UITableView, by way of an NSFetchedResultsController. The error I'm getting is on this line of code:

NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest: fetchRequest managedObjectContext: [self managedObjectContext] sectionNameKeyPath: nil cacheName: @""];

It seems that the problem is that it's trying to load an empty object into an array. I'm guessing this means that it hasn't found the objects inside the .sqlite file. Is that likely to be the case? If so, how can I begin trying to track down why that might be?

Here's some code, if you need any more, please ask:

From AppDelegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    UINavigationController *nav = (UINavigationController *) self.window.rootViewController;
    FQQuotesTableViewController *quotesTableViewController = (FQQuotesTableViewController *) [[nav viewControllers] objectAtIndex: 0];
    quotesTableViewController.managedObjectContext = self.managedObjectContext;
    quotesTableViewController.test = @"Hello!";
    return YES;
}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }

    NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex: 0];
    NSString *storePath = [documentsPath stringByAppendingPathComponent: @"Quotes.sqlite"];
    NSURL *storeURL = [NSURL fileURLWithPath: storePath];

    if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURL path]]) {
        NSURL *preloadURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Quotes" ofType:@"sqlite"]];
        NSError* err = nil;

        if (![[NSFileManager defaultManager] copyItemAtURL:preloadURL toURL:storeURL error:&err]) {
            NSLog(@"Oops, could copy preloaded data");
        }
    }

    NSError *error = nil;
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![_persistentStoreCoordinator addPersistentStoreWithType: NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }    

    return _persistentStoreCoordinator;
}

And from my ViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSError *error;
    if (![self.fetchedResultsController performFetch: &error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();    
    }
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return [[_fetchedResultsController sections] count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    id <NSFetchedResultsSectionInfo> secInfo = [[_fetchedResultsController sections] objectAtIndex: section];
    return [secInfo numberOfObjects];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    NSManagedObject *blah = [self.fetchedResultsController objectAtIndexPath: indexPath];
    cell.textLabel.text = [blah valueForKey: @"quote"];

    return cell;
}

#pragma mark - Fetched Results Controller

- (NSFetchedResultsController *) fetchedResultsController
{
    if (_fetchedResultsController != nil) {
        return _fetchedResultsController;
    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName: @"Quote" inManagedObjectContext: [self managedObjectContext]];
    [fetchRequest setEntity:entity];

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:nil ascending: YES];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    [fetchRequest setSortDescriptors:sortDescriptors];

    [fetchRequest setFetchBatchSize: 50];

    NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest: fetchRequest managedObjectContext: [self managedObjectContext] sectionNameKeyPath: nil cacheName: @""];
    self.fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;

    return _fetchedResultsController;
}

回答1:


Have you tried to set a key (a attribute name of your model) for sortDescriptor? I think it is the issue.

NSSortDescriptor *sortDescriptor =
  [[NSSortDescriptor alloc] initWithKey:nil  // set key for the descriptor
                              ascending:YES];


来源:https://stackoverflow.com/questions/15067842/nsfetchedresultscontroller-seems-to-be-inserting-empty-objects-into-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!