2011-05-01 59 views
3

在準備更新我的應用程序時,我發現了一個奇怪的問題,迄今爲止一直是一個頭疼的問題。託管對象上下文保存不會使其持久存儲

我有一個簡單的方法,獲取一個託管對象,更新一個屬性,然後將更改保存到持久性存儲。奇怪的是,有些時候,它似乎並沒有實際上一直保存到數據庫的堆棧中,但它成功保存並返回true,並且不會填充NSError對象。

我已通過打開SQL日誌記錄驗證了這一點 - 在一次調用中,我沒有看到UPDATE語句,但是在使用相同輸入的同一方法的第二次調用中,我看到UPDATE。

真的很奇怪。我一定在做錯事,但我一整天都在盯着這件事,而我無法弄清楚。

這裏是有問題的方法:

+ (void)markTemplateAsPurchasedWithProductID:(NSString *)productID inContext:(NSManagedObjectContext *)context {  
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"TripTemplate" inManagedObjectContext:context]; 
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"(productID = %@)", productID]]; 
[fetchRequest setEntity:entity]; 
NSError *error; 
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error]; 
[fetchRequest release]; 

if ([fetchedObjects count] > 0) { 
    TripTemplate *template = [fetchedObjects lastObject]; 
    template.purchased = [NSNumber numberWithBool:YES]; 

    NSLog(@"Marking '%@' as Purchased: %@", template.name, template.purchased); 

    NSError *saveError;   
    if (![context save:&saveError]) 
     NSLog(@"Error Saving Purchased For Template: %@ - %@", template, saveError); 
} else { 
    ... 
    //log fetch error 
} 
} 

這裏有兩套日誌,我看到調用此方法時。

我已經驗證,在這兩種情況下,它們都是從主線程調用的。

他們正在一個接一個地運行。

試驗#1(沒有SQL更新):

2011-04-30 17:25:27.107應用[15024:707] CoreData:SQL:SELECT 0,t0.Z_PK,t0.Z_OPT, t0.ZLASTAPPSTOREPRICE,t0.ZPURCHASED,t0.ZISFREE,t0.ZNAME,t0.ZPRODUCTID,t0.ZSERVERID,t0.ZTRIPDESCRIPTION,t0.ZAUTHORDESCRIPTION,t0.ZAUTHORURL,t0.ZCREATEDAT,t0.ZAUTHORNAME FROM ZTRIPTEMPLATE t0 WHERE t0.ZPRODUCTID =?

2011-04-30 17:25:27.110應用[15024:707] CoreData:註釋:SQL連接提取時間:0.0028s

2011-04-30 17:25:27.111應用[15024:707 ] CoreData:註釋:總提取執行時間:1行0.0043s。

2011-04-30 17:25:27.112應用[15024:707]標記 '史蒂夫的創作' 作爲購買:1

運行#2(SQL更新):

2011-04 -30 17:27:37.536 App [15024:707] CoreData:sql:SELECT 0,t0.Z_PK,t0.Z_OPT,t0.ZLASTAPPSTOREPRICE,t0.ZPURCHASED,t0.ZISFREE,t0.ZNAME,t0.ZPRODUCTID,t0。 ZSERVERID,t0.ZTRIPDESCRIPTION,t0.ZAUTHORDESCRIPTION,t0.ZAUTHORURL,t0.ZCREATEDAT,t0.ZAUTHORNAME FROM ZTRIPTEMPLATE t0 WHERE t0.ZPRODUCTID =?

2011-04-30 17:27:37.537應用[15024:707] CoreData:註釋:SQL連接提取時間:0.0015s

2011-04-30 17:27:37.538應用[15024:707 ] CoreData:註解:總提取執行時間:1行0.0024s。

2011-04-30 17:27:37.539應用[15024:707]標記 '史蒂夫的創作' 作爲購買:1

2011-04-30 17:27:37.540應用[15024:707] CoreData :sql:BEGIN EXCLUSIVE

2011-04-30 17:27:37。542 App [15024:707] CoreData:sql:UPDATE ZTRIPTEMPLATE SET ZPURCHASED =?,Z_OPT =?哪裏Z_PK =? AND Z_OPT =?

2011-04-30 17:27:37.544應用[15024:707] CoreData:SQL:COMMIT

任何建議,我可能會開始尋找我的問題?

在這兩種情況下,抓取都起作用,所以看起來MOC至少能夠與商店交談。

+0

您是否依靠SQL日誌記錄來告訴您沒有任何更改或託管對象本身不會更改?更改是否在重新啓動時出現? – TechZen 2011-05-01 19:06:28

+0

我剛剛使用SQL日誌記錄來驗證。如果我在保存之前和之後記錄購買的屬性,它顯示爲true,但如果在保存後刷新對象,則「購買」屬性將返回false。 – Hunter 2011-05-01 19:07:41

+0

你有多個上下文或多個線程/操作? – TechZen 2011-05-01 19:08:01

回答

1

在查看代碼時,我可以建議的唯一錯誤就是您以某種方式將不同的上下文傳遞給該方法。如果是這樣,並且您不合並上下文,那麼如果您保存在另一箇中而不是另一箇中,則不會顯示更改。

我建議記錄整個模板對象,上下文和上下文的updatedObjects。你需要確保你正在與你認爲你是對象的對話。

+0

聽起來像是值得仔細檢查的東西。我一直在關注這個問題,直到我的大腦開始融化,那時候我開始做出危險的假設。將回報... – Hunter 2011-05-01 19:20:46

+0

這是很好的建議。原來,我混淆了一個代碼路徑中傳入該方法的MOC,這導致了這種奇怪。所以,結果是非常簡單的用戶錯誤的情況。有時候你只能和某人聊聊。謝謝! – Hunter 2011-05-01 19:57:42

相關問題