2011-02-26 34 views
0

我對coredata很新。我的目標是將數據寫入一個函數內的不同實體。我已經在我的應用程序委託中初始化coredata並將其傳遞給我的viewcontroller。在我的viewController中,我想決定情境依賴,應該使用哪個實體。所以我編輯fetchedResultsController-方法的像這樣的代碼:如何在一個方法內的兩個不同實體中插入數據?

-(NSFetchedResultsController *)fetchedResultsControllerForEntityWithString:(NSString*)theEntityString { 
... 
NSEntityDescription *entity = [NSEntityDescription entityForName:theEntityString inManagedObjectContext:self.managedObjectContext]; 
    [fetchRequest setEntity:entity]; 
... 
} 

第二種方法我改變是saveContext:

-(void)saveContextForEntityWithString:(NSString*)theEntityString { 
    NSManagedObjectContext *contex = [self fetchedResultsControllerForEntityWithString:theEntityString managedObjectContext]; 
... 
} 

對於插入新的數據,我寫一個新的方法:

-(void)insertEntityForString:(NSString*)theEntityName { 
NSManagedObjectContext *context = [[self fetchedResultsControllerForEntityWithString:theEntityName] managedObjectContext]; 
NSEntityDescription *entity = [[[self fetchedResultsControllerForEntityWithString:theEntityName] fetchRequest] entity]; 
NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context]; 

if ([newManagedObject isKindOfClass:[myClass1 class]]) { 
    newManagedObject.testValue:[NSDate date]; 
} else if ([newManagedObject isKindOfClass:[myClass2 class]]) { 

} 

}

不幸的是,這種方法不會成功。 Xcode不知道testValue是否存在,並引發錯誤。

希望你能幫助我更好地理解coredata應該如何正確設置。

非常感謝你的幫助。

回答

0

這個測試:

if ([newManagedObject isKindOfClass:[myClass1 class]]) { 

...總是會失敗,因爲這條線:

NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context]; 

...始終將newManagedObject定義爲NSManagedObject

混淆entites,NSManagedObject類和NSManagedObject子類很常見。

實體抽象類似於類定義。他們告訴託管對象上下文如何構建對象中的數據。

NSManagedObject令人困惑,因爲NSManagedObject的任何泛型實例都可以使用關聯存儲來存儲來自任何實體的數據。關聯存儲像字典一樣工作。該實體爲字典提供密鑰。所以,像這樣的一行:

NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context]; 

...插入一個通用NSManagedObject實例到上下文,然後將其聯想存儲的鍵值名,將名稱由實體定義。對象的類始終是NSManagedObject,無論實體提供其密鑰。

當您創建鎖定到特定實體的NSManagedObject的子類時,您只會看到不同的類。實體的關鍵名稱成爲該類的定義屬性。

我不確切知道你在設計中通過移動fetchedResultControllers來拍攝什麼。通常,這會產生一個非常混亂的界面,因爲用戶期望單個表格呈現相同的數據。通常情況下,您將使用不同的表格來呈現來自不同實體的數據,以便用戶可以將自己定位到數據更改。

但是,如果您仍想這樣做,最簡單的方法是爲您的tableview控制器定義一個currentEntity屬性。像這樣:

@property(nonatomic, retain) NSString *currentEntity; 

...然後添加一個測試你的fetchedResultsController getter方法:

- (NSFetchedResultsController *)fetchedResultsController { 

    if (fetchedResultsController != nil) { 
     if ([[[fetchedResultsController entity] name] isEqualToString:self.currentEntity]) { 
      return fetchedResultsController; 
     } 
    } 
    // configure the FRC as normal but for the fetch entity name use currentEntity 
    NSEntityDescription *entity = [NSEntityDescription entityForName:self.currentEntity inManagedObjectContext:managedObjectContext]; 
    [fetchRequest setEntity:entity]; 
    //.... 

現在,更改控制器實體獲取,你只需要改變存儲在currentEntity名稱。下一次調用FRC時,它將自動重置爲新的實體提取。

但是,我必須警告你,FRC和關聯的表方法並不是真正爲這種交換設置的。你將不得不小心表更新,我認爲它不可靠或穩定。

+0

哇。感謝您的好解釋!我有一個應用程序「分離」爲兩部分:在停車場停車並在外面停車。所以我爲每個部分定義了一個實體:http://img64.imageshack.us/i/bildschirmfoto20110227u.png/所以你認爲我可以用另一種方式設計我的模型嗎?正如我所說我對核心數據真的很陌生,並希望儘可能地學習:) – rdesign 2011-02-27 12:09:27

0

newManagedObject.testValue:[NSDate date];

:當你修改問題的代碼發生了錯字?

您可以隨時使用setValue:forKey:設置核心數據對象的屬性。 像

[newManagedObject setValue:[NSDate date] forKey:@"testValue]; 

另一種選擇是一個抽象的實體,它的對象,你會在課堂上你的兩個實體的超類使用

+0

哦是的,只是一個拼錯。感謝您的回答。那麼你認爲我的代碼是不錯的起點嗎? – rdesign 2011-02-27 12:26:53

0

如果您已經定義MyClass1的和myClass2作爲子類,你可以做eomthing這樣的:

-(void)insertEntityForString:(NSString*)theEntityName { 
NSManagedObjectContext *context = [[self fetchedResultsControllerForEntityWithString:theEntityName] managedObjectContext]; 
NSEntityDescription *entity = [[[self fetchedResultsControllerForEntityWithString:theEntityName] fetchRequest] entity]; 
NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context]; 

if ([newManagedObject isKindOfClass:[myClass1 class]]) { 
    myClass1 *newMyClass1 = (myClass1)newManagedObject; 
    newMyClass1.testValue = [NSDate date]; 
} else if ([newManagedObject isKindOfClass:[myClass2 class]]) { 
    myClass2 *newMyClass2 = (myClass2)newManagedObject; 
    newMyClass2.someOtherValue = @"Hi, Hello"; 
} 

如果沒有,你的if語句應該是這樣的:

if ([newManagedObject isKindOfClass:[myClass1 class]]) { 
    [newManagedObject setValue:[NSDate date] forKey:@"testValue"]; 
} else if ([newManagedObject isKindOfClass:[myClass2 class]]) { 
    [newManagedObject setValue:@"Hi, Hello" forKey:@"someOtherName"]; 
} 
相關問題