这段代码有啥问题?不从核心数据填充表! iPad

Posted

技术标签:

【中文标题】这段代码有啥问题?不从核心数据填充表! iPad【英文标题】:whats wrong with this code? not populating table from core data!! iPad这段代码有什么问题?不从核心数据填充表! iPad 【发布时间】:2010-12-24 00:15:49 【问题描述】:

请帮我解决这个问题(我现在快疯了!),我的项目正在将数据正确保存到 coredata 中的 sqlite db,正如在 SQLite 图形管理器中检查的那样,但我似乎无法显示它在表格视图中,我需要在我的 viewController 中使用我的表格(小表格不是整个屏幕),

如果您觉得大方,请查看我的小示例项目 Here Thankyou!

这里是*viewcontroller.h的代码

(请注意,我在表格视图中包含了一个 IBoutlet,因为 tableView 不是 UIViewController 中的实例!)这样做是否正确? 另外,我在调用 tableView 时收到 7 个警告>“tableView”的本地声明隐藏了实例变量

#import <UIKit/UIKit.h>


@interface CoreDataEnsaViewController : UIViewController 
<UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate> //va     controller delegate??




UITextField *name;
UITextField *address;
UITextField *phone;
UILabel         *status;


//la table
//NSMutableArray *array;

//la tabla??
UITableView *tableView;
NSFetchedResultsController *_fetchedResultsController;
NSManagedObjectContext *_context;  


@property (nonatomic, retain) IBOutlet UITextField *name;
@property (nonatomic, retain) IBOutlet UITextField *address;
@property (nonatomic, retain) IBOutlet UITextField *phone;
@property (nonatomic, retain) IBOutlet UILabel *status;

@property (nonatomic, retain) IBOutlet UITableView *tableView;

@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, retain) NSManagedObjectContext *context;

- (IBAction) saveData;
- (IBAction) findContact;
- (IBAction) showbtn:(id) sender;

@end

这里是 *viewController.m

#import "CoreDataEnsaViewController.h"
#import "CoreDataEnsaAppDelegate.h"
#import "ShowViewController.h"

#import "Contacts.h"

@implementation CoreDataEnsaViewController

ShowViewController *showView;

@synthesize name, address, phone, status, tableView;

@synthesize context = _context;
@synthesize fetchedResultsController = _fetchedResultsController;

-(IBAction) showbtn:(id) sender 

showView = [[ShowViewController alloc] initWithNibName:@"ShowViewController"  bundle:nil];

//anima
[UIView beginAnimations:@"flipping view" context:nil];
   [UIView setAnimationDuration:1];
   [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown 
                       forView:self.view cache:YES];

[self.view addSubview:showView.view];
[UIView commitAnimations];  



  - (void) saveData
 
CoreDataEnsaAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];

NSManagedObjectContext *context = [appDelegate managedObjectContext];

NSManagedObject *newContact;

newContact = [NSEntityDescription insertNewObjectForEntityForName:@"Contacts"  inManagedObjectContext:context];

[newContact setValue:name.text forKey:@"name"];
[newContact setValue:address.text forKey:@"address"];
[newContact setValue:phone.text forKey:@"phone"];

name.text = @"";
address.text = @"";
phone.text = @"";

NSError *error;
[context save:&error];
status.text = @"Contact saved";
    

    - (void) findContact
   
CoreDataEnsaAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];

NSManagedObjectContext *context = [appDelegate managedObjectContext];

NSEntityDescription *entityDesc = [NSEntityDescription entityForName:@"Contacts" inManagedObjectContext:context];

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

[request setEntity:entityDesc];

NSPredicate *pred = [NSPredicate predicateWithFormat:@"(name = %@)", name.text];

[request setPredicate:pred];

NSManagedObject *matches = nil;
NSError *error;

NSArray *objects = [context executeFetchRequest:request error:&error];

if ([objects count] == 0) 
    status.text = @"No matches";
 else 
    matches = [objects objectAtIndex:0];
    address.text = [matches valueForKey:@"address"];
    phone.text = [matches valueForKey:@"phone"];
    status.text = [NSString stringWithFormat:@"%d matches found", [objects  count]];

[request release];
    

- (NSFetchedResultsController *)fetchedResultsController 

if (_fetchedResultsController != nil) 
    return _fetchedResultsController;


NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Contacts" inManagedObjectContext:_context];
[fetchRequest setEntity:entity];

//NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"details.closeDate"  ascending:NO];
//[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];

[fetchRequest setFetchBatchSize:20];

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

[fetchRequest release];
[theFetchedResultsController release];

return _fetchedResultsController;    







// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad 
[super viewDidLoad];






- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation 
// Overriden to allow any orientation.
return YES;



- (void)didReceiveMemoryWarning 
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Release any cached data, images, etc that aren't in use.



- (void)viewDidUnload 
self.name = nil;
self.address = nil;
self.phone = nil;
self.status = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;




//tabla

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
return 1;


- (NSInteger)tableView:(UITableView *)tableView

numberOfRowsInSection:(NSInteger)section 

 id <NSFetchedResultsSectionInfo> sectionInfo = [[_fetchedResultsController  sections] objectAtIndex:section];
 return [sectionInfo numberOfObjects];

//return [array count];
//return [[fetchedResultsController sections] count];
  


- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath 

    Contacts *info = [_fetchedResultsController objectAtIndexPath:indexPath];
    cell.textLabel.text = info.name;
    cell.detailTextLabel.text = [NSString stringWithFormat:@"%@, %@", info.address, info.phone];




  //---insert individual row into the table view---

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

static NSString *CellIdentifier = @"Cell";
//---try to get a reusable cell---

UITableViewCell *cell = [tableView  dequeueReusableCellWithIdentifier:CellIdentifier];



//---create new cell if no reusable cell is available---

if (cell == nil) 

    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];





// Set up the cell...
[self configureCell:cell atIndexPath:indexPath];



return cell;

  



  - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 

[tableView deselectRowAtIndexPath:indexPath animated:YES];





 //tabla end



 - (void)dealloc 
[name release];
[address release];
[phone release];
[status release];

self.fetchedResultsController = nil;
self.context = nil;

[super dealloc];



 #pragma mark NSFetchedResultsControllerDelegate methods

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller 
    // The fetch controller is about to start sending change notifications,  so    prepare the table view for updates.
    [self.tableView beginUpdates];



- (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];
            // Reloading the section inserts a new row and ensures that titles are updated appropriately.
            [tableView reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade];
            break;
    



- (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)controllerDidChangeContent:(NSFetchedResultsController *)controller 
    // The fetch controller has sent all current change notifications, so tell the table view to process all updates.
    [self.tableView endUpdates];



@end

xib 中的连接是> 表视图 出口: 数据源-----------文件所有者; 委托-------------文件所有者; 参考网点 tableView-------------文件所有者; 非常感谢!!!!

【问题讨论】:

好的,链接中的代码已更新到我的上一个项目,谢谢!! 你的项目链接好像下线了... 链接现在可以工作,但问题仍然存在!!,干杯 【参考方案1】:

至于“NSInternalConsistencyException”,请根据您的代码检查托管对象模型,并确保您正确调用它。如果做不到这一点,您是否完成了干净、重新启动的 XCode、重新启动计算机、从模拟器中删除应用程序,以及通常的事情?如果您对文件进行了更改或将其换出,旧的东西有时会“潜伏”并导致这些问题。如果做不到这一点,有时当我遇到令人困惑的核心数据问题时,从头开始重建模型文件并自动创建子类将解决它......不知道为什么。

我知道这不是您的问题,但不鼓励简单地为托管对象上下文调用应用程序委托 - 尽管它确实有效并且您会在一些代码示例中看到它,但这不是最佳实践。它在您的项目中引入了不必要的依赖,这将使您的代码更难维护。应用程序委托应仅用于处理其设计的系统级事件,而不应“滥用”用于其他目的。更好的方法是为每个需要它的控制器创建一个托管对象上下文属性,并在创建该控制器时传递引用。您的 App Delegate 会将其传递给 didFinishLaunchingWithOptions 中的根视图控制器(只需设置接收控制器的属性),如下所示:

-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions...

  UINavigationController *navController = self.window.rootViewController
  MyViewController *controller = navController.viewControllers[0];
  controller.managedObjectContext = self.managedObjectContext;

  return YES;

当根视图控制器需要将 MOC 传递给另一个控制器时,会发生这样的情况:

-(void)prepareForSegue...

  MyOtherController *otherController = [segue destinationViewController];
  controller.managedObjectContext = self.managedObjectContext;

对于每个需要它的控制器,依此类推。这样您就不会引入不必要的依赖项,从而降低您的代码模块化和可重用性。

希望这会有所帮助。

【讨论】:

【参考方案2】:

尝试添加此代码以在您的 viewDidLoad 方法中执行数据获取:

NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) 
    NSLog(@"Unsolved error: %@, %@", error, [error userInfo]);
    abort();

【讨论】:

由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“+entityForName: 找不到实体名称“联系人”的 NSManagedObjectModel 如果我在视图中包含了加载的代码,我会收到上述错误!谢谢,有什么问题啊 :( 这个错误让我觉得你的 managedObjectContext 有什么问题...尝试仔细检查代码,如果您还没有这样做,请尝试查看 Apple 提供的项目。

以上是关于这段代码有啥问题?不从核心数据填充表! iPad的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Room 不从资产中填充数据库?

这段代码有啥错误

看看这段代码,如果有啥我可以改变的,请告诉我

为啥 UITableView 不从数组中填充

这段代码有啥问题? [关闭]

$this->Model->save() :这段代码有啥问题?