2009-09-03 34 views
0

我有一个模型,我有一个Person实体和一个Picture实体。在我的图片实体中,我有一个与Person关系的属性。这个Core Data示例为什么会崩溃?

我想有一个关于如何将图片添加到人的例子,因为我所做的不起作用。

-(BOOL)savePicture:(NSString *)urlPicture:(Person *)person{ 
SettingsSingleton *userSettings = [SettingsSingleton sharedManager];  
NSManagedObjectContext *managedObjectContext = [userSettings managedObjectContext]; 
NSEntityDescription *myContentEntity = [NSEntityDescription entityForName:@"Pictures" inManagedObjectContext:managedObjectContext]; 
NSManagedObject *contentToSave = [[NSManagedObject alloc] initWithEntity:myContentEntity insertIntoManagedObjectContext:managedObjectContext]; 

[contentToSave setValue:urlPicture forKey:@"url"]; 
[contentToSave setValue:person forKey:@"relatedPerson"]; 

[managedObjectContext insertObject:contentToSave]; 

NSError *error; 
if ([managedObjectContext save:&error]){ 
    //Deal with errors 
    NSLog(@"Error"); 
      return NO; 
} 
return YES; 
} 

它崩溃就行了,如果([managedObjectContext保存:&错误]),并在控制台中我有这些错误:

-[UITableViewCell objectID]: unrecognized selector sent to instance 0x135c2b0 Serious application error. Exception was caught during Core Data change processing: ***  
-[UITableViewCell objectID]: unrecognized selector sent to instance 0x135c2b0 with userInfo (null) *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** 
-[UITableViewCell objectID]: unrecognized selector sent to instance 0x135c2b0' 

,在我以前的观点,我有以下代码

- (void)viewDidLoad { 
[super viewDidLoad]; 
SettingsSingleton *settings = [SettingsSingleton sharedManager];  
managedObjectContext = [settings managedObjectContext]; 
fetchedResultsController = [settings fetchedResultsController]; 
fetchedResultsController.delegate=self; 

NSError *error; 
if (![[self fetchedResultsController] performFetch:&error]) { 
    // Handle the error... 
} 
[settings release]; 

self.table = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 416) style: UITableViewStyleGrouped]; 
[table setDataSource:self]; 
table.delegate=self; 
[self.view addSubview: self.table]; 
} 


- (NSFetchedResultsController *)fetchedResultsController { 

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

Person *personTmp=[[Person alloc] init]; 
personTmp=[personTmp getPersonById:self.personId]; 

/* 
Set up the fetched results controller. 
*/ 
// Create the fetch request for the entity. 
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
// Edit the entity name as appropriate. 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Pictures" inManagedObjectContext:managedObjectContext]; 
NSPredicate *predicate =[NSPredicate predicateWithFormat:@"relatedPerson == %@ AND contentType == %d",personTmp, CONTENT_DATA_PICTURE]; 

[fetchRequest setEntity:entity]; 
[fetchRequest setPredicate:predicate]; 

// 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:managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"]; 
aFetchedResultsController.delegate = self; 
self.fetchedResultsController = aFetchedResultsController; 

[aFetchedResultsController release]; 
[fetchRequest release]; 
[predicate release]; 
[personTmp release]; 


return fetchedResultsController; 
}  


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

static NSString *CellIdentifier = @"Cell"; 

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) { 
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; 
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 
} 
if(indexPath.row==0){ 
    [email protected]"Add a picture"; 
} 
else{ 
    int nb=indexPath.row-1; 
    NSIndexPath *ip = [NSIndexPath indexPathForRow: nb inSection:indexPath.section]; 
    NSManagedObject *managedObject = [fetchedResultsController objectAtIndexPath:ip]; 
    cell.textLabel.text = [[managedObject valueForKey:@"url"] description]; 
    [ip release]; 
} 
return cell; 
} 


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
int nb=[[fetchedResultsController sections] count]; 
if (nb == 0) { 
    nb = 1; 
} 
return nb; 
} 


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

NSArray *sections = [fetchedResultsController sections]; 
NSUInteger count = 0; 
if ([sections count]) { 
    id <NSFetchedResultsSectionInfo> sectionInfo = [sections objectAtIndex:section]; 
    count = [sectionInfo numberOfObjects]; 
} 
return count+1; 
} 

回答

1

首先,您不必调用'insertObject'。从苹果documentation

如果上下文不为零,则此方法调用[上下文insertObject:self](这将导致调用awakeFromInsert)。

所以你冗余插入对象两次。不知道这可能会产生什么负面影响,但它不可能是好的。

至于错误,它看起来像您的代码的其他部分可能是罪魁祸首。这个消息意味着什么基本上是你正在尝试访问UITableViewCell的CoreData对象ID。由于在保存期间发生这种情况,我想在这个函数之前的某个时刻,您可能会将UITableViewCell插入到managedObjectContext中,然后当您实际继续保存时,您只会在此处冒出。

+0

我现在有一个不同的错误,当我评论 - (NSFetchedResultsController *)fetchedResultsController方法中的代码,我可以正确地添加我的照片,否则我有:程序接收到的信号:“EXC_BAD_ACCESS”。 – Mathieu 2009-09-04 21:20:52

+1

您的谓词过度释放,可能还有personTmp(取决于getPersonById是否返回自动释放对象)。崩溃来自这些过度释放的对象。您应该阅读Objective-C中的内存管理(Google“Objective-c内存管理”,应该是第一个结果)。此外,如果getPersonById返回一个不同的人物对象,那么你也正在泄漏你分配的那个对象 - 在此之上。 – bobDevil 2009-09-04 22:49:00

+0

哦是的,现在的作品 但我必须释放谓词变量无论如何,我必须使它成为该类的全局变量,并释放它在 - (void)dealloc – Mathieu 2009-09-05 00:07:25

6

我有一个非常类似的错误发生。我有一个navController首先加载customTypeA viewController,然后加载customTypeB viewController。这两个viewController都使用Core Data和fetchedResultsControllers作为tableview的数据源。 customTypeB的功能是将一个新的数据对象添加到customTypeA的数据源。一旦这样做,我会收到上述错误“Serious Error in Core Data, Unrecognized Selector. EXC_BAD_ACCESS”;但是我的错误表明无法识别的选择器是“controllerWillChangeContent”。我的两个viewControllers都使用了fetchedViewController委托方法“controllerWillChangeContent,controllerDidChangeObject ...,controllerDidChangeContent”。

我注意到,当viewControllerB改变了controllerA的数据时,控制器A的fetchedResultsController被激活,即使controllerB还没有被“弹出”。所以我想,也许controllerB的代表被调用。看看Core Data编程文档,我看到他们推荐使用fetchedResultsController的每个视图,你应该实现viewWillDisappear并且在它里面,set fetchedResultsController = nil;对我来说,这解决了我的问题。

也仅供参考 - 在为Snow Leopard安装XCODE 3.2之前,我没有调用fetchedResultsControllers的非可见viewControllers委托的问题。代码在Leopard的Xcode3.1中运行良好。

+0

我和你在一起。基本上,如果您在不同的viewController中使用相同的managedObjectContext,并且您的fetchedViewController委托被其中一个挂钩,那么您在数据对象中更改的所有内容都将导致调用委托方法。 – digdog 2010-01-13 07:37:04

+0

在我的dealloc中,我忘了'self.fetchedResultsController = nil;'。这样做解决了我的问题。做'viewWillDisappear:'和'viewWillAppear:'可能是矫枉过正:) – 2010-02-11 15:41:59

+0

在“严重的应用程序错误。在核心数据更改处理过程中发生异常情况:'多日来,我开始进行谷歌搜索,并再次发现这一情况。在'viewDidDisappear:'和'viewWillAppear:'解决我所有的问题。用一个不可见的NSFetchedResultsController搞定会发疯。我不推荐它。 – 2010-05-06 19:45:23