开发者

from NSFetchedResults objectAtIndex:0 returning 0

I've been banging my head on this one specific issue for about 2 hours now, reading through documentation and examples and I just can't wrap my head around it. I have core data models Person and Photo, and they're linked. I'm trying to display a UITableView with the contents and

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

keeps returning 0. Here is the relevant code. I know there is data in my core data because I can look at it with sqlite in terminal.

AppDelegate.h

@interface PaparazziAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;

    UITabBarController *tabController;
    UINavigationController *mainNavController;
    UINavigationController *recentsNavController;
    PersonListViewController  *personListView;
    PhotoListViewController *recentsList;
    PhotoDetailViewController *photoDetail;

    FlickrFetcher *fetcher;
    NSManagedObjectContext *currentContext;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;

@property (nonatomic, retain) IBOutlet UITabBarController *tabController;
@property (nonatomic, retain) IBOutlet UINavigationController *mainNavController, *recentsNavController;

@end

AppDelegate.m

#import "PaparazziAppDelegate.h"

@implementation PaparazziAppDelegate

@synthesize window;
@synthesize tabController, mainNavController, recentsNavController;

#pragma mark -
#pragma mark Application lifecycle

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {   

    // Setup the database instances for access.
    fetcher = [FlickrFetcher sharedInstance];

    // Check to see if the database exists, if not, load the plist and populate.
    if ([fetcher databaseExists])
        NSLog(@"I'm here!");
    else {
        NSLog(@"No database yet!");

        currentContext = [fetcher managedObjectContext];

        /* -- REMOVED FOR READABILITY -- 
        A chunk of code for creating fresh data from a plist if the database doesn't yet exist.
        I know this part works because I can see the data using the terminal */

        [currentContext release];
    }
    // End of the plist loading and database creation.

    personListView = [[PersonListViewController alloc] initWithStyle:UITableViewStylePlain];
    personListView.title = @"Contacts";
    [mainNavController pushViewController:personListView animated:NO];
    [personListView release];

    recentsList = [[PhotoListViewController alloc] initWithNibName:@"PhotoListViewController" bundle:[NSBundle mainBundle]];
    recentsList.title = @"Recents";
    [recentsNavController pushViewController:recentsList animated:NO];
    [recentsList release];

    // setting up view icons
    UITabBarItem *contactsIcon = [[UITabBarItem alloc]
                          initWithTabBarSystemItem:UITabBarSystemItemContacts tag:0];
    mainNavController.tabBarItem = contactsIcon;
    [contactsIcon release];
    UITabBarItem *recentsIcon = [[UITabBarItem alloc]
                                  initWithTabBarSystemItem:UITabBarSystemItemRecents tag:0];
    recentsNavController.tabBarItem = recentsIcon;
    [recentsIcon release];

    [self.window addSubview:tabController.view];

    // Override point for custom开发者_如何学运维ization after application launch.

    [self.window makeKeyAndVisible];

    return YES;
}

- (void)dealloc {
    [window release];
    [tabController release];
    [mainNavController release];
    [recentsNavController release];

    [fetcher release];

    [super dealloc];
}


@end

PersonListViewController.h

#import <UIKit/UIKit.h>
#import "FlickrFetcher.h"
#import "Person.h"
#import "Photo.h"

@interface PersonListViewController : UITableViewController {
    NSArray *listOfPeople;

    FlickrFetcher *fetcher;
    NSManagedObjectContext *currentContext;
    NSFetchedResultsController *fetchedResultsController;
}

@property (nonatomic, retain) NSArray *listOfPeople;
@property (nonatomic, retain) NSManagedObjectContext *currentContext;
@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;

@end

And the trouble file, PersonListViewController.m

#import "PersonListViewController.h"

@implementation PersonListViewController

@synthesize listOfPeople, currentContext, fetchedResultsController;

#pragma mark -
#pragma mark Initialization

- (id)initWithStyle:(UITableViewStyle)style {
    // Override initWithStyle: if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization.
        fetcher = [FlickrFetcher sharedInstance];
        currentContext = [fetcher managedObjectContext];

        fetchedResultsController = [fetcher fetchedResultsControllerForEntity:@"Person" withPredicate:nil];
    }
    return self;
}

#pragma mark -
#pragma mark View lifecycle


- (void)viewDidLoad {
    [super viewDidLoad];

    self.title = @"Contacts";
}

#pragma mark -
#pragma mark Table view data source

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

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

// Customize the appearance of table view cells.
- (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];
    }
    Person *person = [fetchedResultsController objectAtIndexPath:indexPath];
    cell.textLabel.text = [person name];

    // Configure the cell...

    return cell;
}

#pragma mark -
#pragma mark Memory management

- (void)dealloc {
    [super dealloc];
}

@end

I have a feeling I'm missing something simple or 1 off, but I just can't seem to find it. [FlickrFetcher sharedInstance] returns a singleton, if I toss a few breakpoints into each .m file, I can see that the object id of *fetcher in each area is the same.


It looks like you haven't used performFetch: to execute the fetched results controller's request. viewWillAppear: is usually a good place to do it:

 - (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    NSError *error = nil;
    if (![fetchedResultsController performFetch:&error]) {
        NSLog(@"fetch error: %@", error);
    }
 }


As an aside - you might consider initialising your fetchedResultsController in viewDidLoad rather than initWithStyle:, then you can drop it in viewDidUnload and hence free up some memory if the OS needs to unload the view controller.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜