Ios NSFetchedResultsController未按预期获取

Ios NSFetchedResultsController未按预期获取,ios,objective-c,core-data,nsfetchedresultscontroller,Ios,Objective C,Core Data,Nsfetchedresultscontroller,我正在iOS应用程序中使用以下NSFetchedResultsController: - (NSFetchedResultsController *)fetchedResultsController { if (_fetchedResultsController != nil) { return _fetchedResultsController; } NSFetchRequest *fetchRequest = [[NSFetchRequest al

我正在iOS应用程序中使用以下NSFetchedResultsController:

- (NSFetchedResultsController *)fetchedResultsController {

    if (_fetchedResultsController != nil) {
        return _fetchedResultsController;
    }

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

    NSSortDescriptor *sort = [[NSSortDescriptor alloc]
                              initWithKey:@"tdText" ascending:NO];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];

    [fetchRequest setFetchBatchSize:20];

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

    return _fetchedResultsController;

}
为了测试它,我使用以下代码:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    int numero = [self.fetchedResultsController.fetchedObjects count];
    NSLog(@"Numero=",numero);
    switch (section)
    {
        case 2 : return numero;
        case 3 : return 30;
        default : return 8;
    }
}
我确信,实体ToDoItems现在有1个对象(使用SQLite管理器检查),但是NSLog显示
Numero=

我的代码出了什么问题?

您实际上并没有打印NSLog语句中的数字

使用


实际上,您并没有打印NSLog语句中的数字

使用


实际上,您并没有打印NSLog语句中的数字

使用


实际上,您并没有打印NSLog语句中的数字

使用


首先,你的日志不正确,正如我在评论中所说的那样

NSLog(@"numero = %d", numero);
然后应该正确实现表视图的数据源方法。e、 g

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

- (NSInteger)tableView:(UITableView *)tableView
    numberOfRowsInSection:(NSInteger)section {
    id  sectionInfo =
        [[fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects];
}
numero
这里是
[sectionInfo numberOfObjects]


有关更多信息,请参阅核心数据编程指南。这是您的参考手册。

首先,您的日志不正确,正如我在评论中所说的

NSLog(@"numero = %d", numero);
然后应该正确实现表视图的数据源方法。e、 g

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

- (NSInteger)tableView:(UITableView *)tableView
    numberOfRowsInSection:(NSInteger)section {
    id  sectionInfo =
        [[fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects];
}
numero
这里是
[sectionInfo numberOfObjects]


有关更多信息,请参阅核心数据编程指南。这是您的参考手册。

首先,您的日志不正确,正如我在评论中所说的

NSLog(@"numero = %d", numero);
然后应该正确实现表视图的数据源方法。e、 g

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

- (NSInteger)tableView:(UITableView *)tableView
    numberOfRowsInSection:(NSInteger)section {
    id  sectionInfo =
        [[fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects];
}
numero
这里是
[sectionInfo numberOfObjects]


有关更多信息,请参阅核心数据编程指南。这是您的参考手册。

首先,您的日志不正确,正如我在评论中所说的

NSLog(@"numero = %d", numero);
然后应该正确实现表视图的数据源方法。e、 g

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

- (NSInteger)tableView:(UITableView *)tableView
    numberOfRowsInSection:(NSInteger)section {
    id  sectionInfo =
        [[fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects];
}
numero
这里是
[sectionInfo numberOfObjects]


有关更多信息,请参阅核心数据编程指南。这是您的参考手册。

我不确定我是否完全理解您想要实现的目标,但是如果您想要一个UITableView,其中包含固定的部分,某些部分是由核心数据填充的,而其他部分则是硬编码的,比如边栏菜单,那么您需要执行以下操作。请注意,在下面的示例中,“任务和可交付成果”部分中的项目是使用fetchedResultsController从核心数据中获取的(不过,只进行正常的获取就可以了,但我太懒了,没有删除fetchedResultsController代码!)。我所做的就是得到一个结果数组,所以我不使用任何委托方法

节在sectionsArray中定义,每个节项包含在单独的数组中,并存储在名为sectionMenus的字典中

还请注意,在从核心数据加载数据时,我加载了一个临时菜单项(“加载,请稍候…”)(iCloud文件可能尚未下载数据)

无论如何,看看这个链接上的视频,看看这个“菜单”在应用程序运行时是什么样子的

在tableViewController.h文件中添加一个
sectionMenus
dictionary和
sectionsArray
数组,如下所示

    @interface MenuViewController : BaseMenuViewController <NSFetchedResultsControllerDelegate> {
        NSArray *sectionsArray;
        NSMutableDictionary *sectionMenus;
        bool _isLoaded;
    }

    @property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;
    @property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;

    @property (strong, nonatomic) NSString *entityName;

@end
@interface MenuViewController:BaseMenuViewController{
NSArray*部分Sarray;
NSMutableDictionary*部分菜单;
bool_已加载;
}
@属性(强,非原子)NSFetchedResultsController*fetchedResultsController;
@属性(强,非原子)NSManagedObjectContext*managedObjectContext;
@属性(强,非原子)NSString*entityName;
@结束
现在在.m文件中,您需要执行以下操作:

#define MENU_PROJECT            @"Project"
#define MENU_TASKS              @"Tasks and Deliverables"
#define MENU_FINANCE            @"Finance"
#define MENU_QUALITY            @"Quality"
#define MENU_IT_SYSTEMS         @"IT Systems"
#define MENU_ADMIN              @"Administration"

#define SUBMENU_SCOPE              @"Scope"
#define SUBMENU_LOADING            @"Loading, please wait..."

@implementation MenuViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    //[self.openingViewController setFilesName:self.filesName];
    //[self.openingViewController setFilesDate:self.filesDate];

    // If we get menu's from the database set this to YES
    _isLoaded = NO;

    sectionMenus = [[NSMutableDictionary alloc] init];
    sectionsArray = [[NSArray alloc] initWithObjects:MENU_PROJECT, MENU_TASKS, MENU_FINANCE, MENU_QUALITY, MENU_IT_SYSTEMS, MENU_ADMIN, nil];

    NSString * bundleID = [[NSBundle mainBundle] bundleIdentifier];

    if ([bundleID isEqualToString:@"au.com.ossh.iProject2FreeiPad"])
    {
        [sectionMenus setObject:[[NSArray alloc] initWithObjects:SUBMENU_SCOPE, nil] forKey:MENU_PROJECT];
        [sectionMenus setObject:[[NSArray alloc] initWithObjects:SUBMENU_LOADING, nil] forKey:MENU_TASKS];
        [sectionMenus setObject:[[NSArray alloc] initWithObjects:@"Expenses", nil] forKey:MENU_FINANCE];
        [sectionMenus setObject:[[NSArray alloc] initWithObjects:@"Issues", nil] forKey:MENU_QUALITY];
        [sectionMenus setObject:[[NSArray alloc] initWithObjects:@"Applications", nil] forKey:MENU_IT_SYSTEMS];
        [sectionMenus setObject:[[NSArray alloc] initWithObjects:@"People", nil] forKey:MENU_ADMIN];
    } else {
        [sectionMenus setObject:[[NSArray alloc] initWithObjects:SUBMENU_SCOPE, nil] forKey:MENU_PROJECT];
        [sectionMenus setObject:[[NSArray alloc] initWithObjects:SUBMENU_LOADING, nil] forKey:MENU_TASKS];
        [sectionMenus setObject:[[NSArray alloc] initWithObjects:@"Expenses", @"Ongoing Costs", @"Timesheets", nil] forKey:MENU_FINANCE];
        [sectionMenus setObject:[[NSArray alloc] initWithObjects:@"Issues", @"Risks", nil] forKey:MENU_QUALITY];
        [sectionMenus setObject:[[NSArray alloc] initWithObjects:@"Applications", @"Interfaces", nil] forKey:MENU_IT_SYSTEMS];
        [sectionMenus setObject:[[NSArray alloc] initWithObjects:@"People", @"Setup", nil] forKey:MENU_ADMIN];        
    }

    // Do any additional setup after loading the view.
    self.entityName = @"ProjectCategory";

    [self fetchedResultsController];

}

- (void)reload {
    NSArray *tadMenus = [self projectCategories];
    if (tadMenus) {
        _isLoaded = YES;
        [sectionMenus setObject:[[NSArray alloc] initWithArray:[self projectCategories]] forKey:MENU_TASKS];
    } else {
        _isLoaded = NO;
    }
}
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    [self.tableView reloadData];
}
// Override this to set your own.
- (NSArray*)sortDescriptors
{
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"sortIndex" ascending:YES];
    NSArray *sortDescriptors = @[sortDescriptor];
    return sortDescriptors;
}

#pragma mark - Fetched results controller

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

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:self.entityName inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    // Set the batch size to a suitable number.
    //[fetchRequest setFetchBatchSize:20];

    [fetchRequest setSortDescriptors:[self sortDescriptors]];

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
    aFetchedResultsController.delegate = self;
    _fetchedResultsController = aFetchedResultsController;

    NSError *error = nil;
    if (![_fetchedResultsController performFetch:&error]) {
        // Replace this implementation with code to handle the error appropriately.
        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    return _fetchedResultsController;
}

- (NSArray*)projectCategories {
    //LOG(@"projectCategories called");
    int count=0;
    id <NSFetchedResultsSectionInfo> sectionInfo;

    if ([[[self fetchedResultsController] sections] count] > 0) {
        sectionInfo = [[[self fetchedResultsController] sections] objectAtIndex:0];
        count = [sectionInfo numberOfObjects];
    } else
        count = 0;
    //FLOG(@" %d categories found", count);
    if (count == 0) return nil;

    NSMutableArray *projectCategories = [[NSMutableArray alloc] initWithCapacity:count];

    for (NSManagedObject *item in _fetchedResultsController.fetchedObjects)
    {
        [projectCategories addObject:item];
        //FLOG(@" adding category %@", [item valueForKey:@"name"]);
    }

    return projectCategories;

}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return [sectionsArray count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return [[sectionMenus objectForKey:[sectionsArray objectAtIndex:section]] count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    return [[sectionsArray objectAtIndex:section] description];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *simpleTableIdentifier = @"SimpleTableItem";
    static NSString *inactiveTableIdentifier = @"InactiveTableItem";
    UITableViewCell *cell;
    NSObject *menuItem = [[sectionMenus objectForKey:[sectionsArray objectAtIndex:[indexPath section]]] objectAtIndex:[indexPath row]];
    NSString *menu = [menuItem description];

    cell.textLabel.text = menu;

    return cell;
}
#定义菜单项目@“项目”
#定义菜单任务@“任务和可交付成果”
#定义菜单_FINANCE@“FINANCE”
#定义菜单质量@“质量”
#定义菜单“IT系统”@“IT系统”
#定义菜单管理@“管理”
#定义子菜单\u范围@“范围”
#定义子菜单_LOADING@“正在加载,请稍候…”
@实现菜单iewcontroller
-(无效)viewDidLoad
{
[超级视图下载];
//[self.openingViewController setfilename:self.filename];
//[self.openingViewController设置文件日期:self.filesDate];
//如果我们从数据库中获取菜单,请将其设置为“是”
_isLoaded=否;
sectionMenus=[[NSMutableDictionary alloc]init];
sectionsArray=[[NSArray alloc]initWithObjects:菜单项目、菜单任务、菜单财务、菜单质量、菜单IT系统、菜单管理、无];
NSString*bundleID=[[NSBundle mainBundle]bundleIdentifier];
if([bundleID IsequalString:@“au.com.ossh.iProject2FreeiPad”])
{
[sectionMenus设置对象:[[NSArray alloc]initWithObjects:子菜单\范围,nil]forKey:菜单\项目];
[sectionMenus设置对象:[[NSArray alloc]initWithObjects:子菜单加载,无]分叉:菜单任务];
[sectionMenus设置对象:[[NSArray alloc]initWithObjects:@“费用”,无]福克斯:菜单和财务];
[sectionMenus设置对象:[[NSArray alloc]initWithObjects:@“问题”,nil]forKey:MENU_-QUALITY];
[sectionMenus设置对象:[[NSArray alloc]initWithObjects:@“应用程序”,nil]forKey:MENU_IT_SYSTEMS];
[sectionMenus设置对象:[[NSArray alloc]initWithObjects:@“People”,nil]forKey:MENU_ADMIN];
}否则{
[sectionMenus设置对象:[[NSArray alloc]initWithObjects:子菜单\范围,nil]forKey:菜单\项目];
[sectionMenus设置对象:[[NSArray alloc]initWithObjects:子菜单加载,无]分叉:菜单任务];
[sectionMenus设置对象:[[NSArray alloc]initWithObjects:@“费用”,“持续成本”,“时间表”,无]forKey:MENU_FINANCE];
[sectionMenus设置对象:[[NSArray alloc]initWithObjects:@“问题”,“风险”,无]福克斯:菜单质量];
[sectionMenus设置对象:[[NSArray alloc]initWithObjects:@“应用程序”,@“接口”,无]forKey:MENU_IT_SYSTEMS];
[sectionMenus setObject:[[NSA]