2010-02-20 26 views
0

我希望有人可以幫助我調試令人難以置信的Core Data崩潰。我最初將數據加載到兩個實體(代表「發言人」和「標題」),然後爲「會話」加載第三個實體,並嘗試將關係設置爲「發言人」和「標題」。 (從會話到演講者和標題是一對一的,從演講者/標題到會話是一對多的)。我使用整數鍵來設置每個關係。難以調試iPhone核心數據錯誤

由於給定的發言人和標題可以指向多個會話,因此我編寫了一個搜索適當的託管對象並返回該對象的函數。然後我爲這種關係做了設定。

這對於演講者關係很好,但對於第二個標題一致而且可怕地崩潰。我用不同的方式重寫了這些代碼幾次,我總是會遇到同樣的問題。無論第二個標題是什麼,問題都存在。所以我必須做一些根本性錯誤的事情,但繼續閱讀更多iPhone 3開發中的核心數據章節,沒有什麼會跳出來。我希望有人可能會看到我錯過的東西(並且一直持續幾天)。 (最後一個注意:無論我將managedObjectContext保存在for循環還是外部,都會發生崩潰,並始終在第二個會話中)。我無盡的感謝和初生的孩子,無論誰能幫助我。

這裏的培訓相關的代碼保存會話實體:

for (NSDictionary *session in self.sessions){ 
     NSManagedObject *newSession = [NSEntityDescription insertNewObjectForEntityForName:[sessionEntity name] inManagedObjectContext:self.managedObjectContext]; 
     [newSession setValue:[session valueForKey:@"ID"] forKey:@"id"]; 
     [newSession setValue:[session valueForKey:@"notes"] forKey:@"notes"]; 
     [newSession setValue:[session valueForKey:@"length"] forKey:@"length"]; 

     //get the speaker value; 
     [newSession setValue:[self setupSpeaker:[session valueForKey:@"speaker"]] forKey:@"speaker"]; 
     NSLog(@"now doing title"); 
     //now get the title value; 
     [newSession setValue:[self setupTitle:[session valueForKey:@"title"]] forKey:@"title"]; 
     NSLog(@"I got back this title:%@", [newSession valueForKey:@"title"]); 

     } 

     if (![self.managedObjectContext save:&error]) { 
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
      abort(); 

}

下面是找到合適的揚聲器和標題實體的關係(我知道這是相當冗餘)代碼

-(NSManagedObject *) setupSpeaker:(NSNumber *)id { 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Speaker" inManagedObjectContext:self.managedObjectContext]; 
    [fetchRequest setEntity:entity]; 

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id==%@",id]; 
    [fetchRequest setPredicate:predicate]; 

    NSError *error; 
    NSArray *items=[self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 
    [fetchRequest release]; 

    if ([items count]>=1){ 
     return [items objectAtIndex:0]; 
    }else{ 
     return 0; 
    } 
} 
-(NSManagedObject *) setupTitle:(NSNumber *)id { 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Title" inManagedObjectContext:self.managedObjectContext]; 
    [fetchRequest setEntity:entity]; 
    NSLog(@"now looking for: %@", id); 
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id==%@",id]; 
    [fetchRequest setPredicate:predicate]; 

    NSError *error; 
    NSArray *items=[self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 
    [fetchRequest release]; 

    if ([items count]>=1){ 
     NSLog(@"found %@", id); 
     return [items objectAtIndex:0]; 
    }else{ 
     return 0; 
    } 
} 

最後,這裏是日誌崩潰時說的:

2010-02-20 16:48:17.134 iconf[1438:207] now looking for: 1 
    2010-02-20 16:48:17.136 iconf[1438:207] found 1 
    2010-02-20 16:48:17.156 iconf[1438:207] I got back this title:<NSManagedObject: 0x3b11a10> (entity: Title; id: 0x3d4a3c0 <x-coredata://B76F62BD-AC82-4335-9013-7529C2471F9C/Title/p6> ; data: { 
     id = 1; 
     session =  (
      0x3d51640 <x-coredata:///Session/t2765697F-14C9-4282-A067-10A2413732B834> 
     ); 
     title = "Bill Gates Speaks"; 
    }) 
    2010-02-20 16:48:17.158 iconf[1438:207] now doing title 
    2010-02-20 16:48:17.158 iconf[1438:207] now looking for: 2 
    2010-02-20 16:48:17.159 iconf[1438:207] found 2 
    2010-02-20 16:48:17.161 iconf[1438:207] I got back this title:<NSManagedObject: 0x3b16fd0> (entity: Title; id: 0x3d4d7a0 <x-coredata://B76F62BD-AC82-4335-9013-7529C2471F9C/Title/p12> ; data: { 
     id = 2; 
     session =  (
      0x3b1b320 <x-coredata:///Session/t2765697F-14C9-4282-A067-10A2413732B835> 
     ); 
     title = "Lecture on Frogs"; 
    }) 
    2010-02-20 16:48:17.161 iconf[1438:207] *** -[NSManagedObject compare:]: unrecognized selector sent to instance 0x3b11a10 
    2010-02-20 16:48:17.162 iconf[1438:207] Serious application error. Exception was caught during Core Data change processing: *** -[NSManagedObject compare:]: unrecognized selector sent to instance 0x3b11a10 with userInfo (null) 
    2010-02-20 16:48:17.163 iconf[1438:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSManagedObject compare:]: unrecognized selector sent to instance 0x3b11a10' 
    2010-02-20 16:48:17.163 iconf[1438:207] Stack: (
+0

如果你可以設置調試器並找出它到底崩潰的線路,它將會有很大的幫助。如果您發佈數據模型的圖表,這樣也可以幫助我們清楚地看到這些關係。 – TechZen 2010-02-21 01:45:10

回答

1

這聽起來像你的數據模型(應該)是這樣的:

音箱< - >>會議
標題< - >>會議

凡揚聲器和標題各有一個將關係分配給會話。

在此基礎上:

我使用一個整數鍵設置每個 關係。

和你的代碼,它看起來像你手動管理關係。你爲什麼做這個?!這是複雜和不必要的。在Core Data數據模型中設置並使用真實關係。

此外,不要使用「id」作爲屬性名稱,因爲它是Objective-C中的關鍵字。

0

謝謝,下面是數據模型的副本。你對基本的佈局是正確的。

http://www.freeimagehosting.net/image.php?debf5866c1.jpg

原因我手動設定的關係是,因爲這是第一次通過該程序,所以我從三個獨立的Plist(一個用於揚聲器,一個用於標題做數據的初始負荷,一個會議)。有一個更好的方法嗎?我可能從根本上不理解核心數據,但似乎如果我每次創建會話實體時都創建了一個新的標題實體,我將擁有從標題到會話的一對一關係,而不是一對一的關係,我想要的很多關係。因此,我將id變量(現在我已經重命名,沒有更改錯誤)作爲第一次加載到核心數據中的關鍵字。之後,我當然會使用核心數據來管理所有這些。有一個更好的方法嗎?

+0

首先,你有兩個SO用戶嗎?爲什麼?接下來,您不應該爲問題發佈其他內容作爲答案。您可以編輯原始問題或在適當的情況下創建新問題。 – gerry3 2010-02-23 18:32:32

+0

您可以從plists進行初始加載,也可以在開發過程中執行初始加載,然後保存該數據庫文件並將其添加到項目中。然後,在您發佈的應用程序中,您將將數據庫文件從您的只讀應用程序包複製到Documents目錄中。請參閱http://stackoverflow.com/questions/2265333/how-to-populate-core-data-with-initial-data/2267000#2267000 – gerry3 2010-02-23 18:41:27

+0

您不瞭解核心數據關係。你應該做的第一件事是爲你的實體創建子類。然後,您可以通過名稱作爲對象的屬性訪問屬性和關係。多對多關係實際上是集合,因此您可以添加單個對象或一組對象,同時在Xcode中創建子類時爲您提供方法。 – gerry3 2010-02-23 18:42:48