2009-09-03 65 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