2011-09-26 73 views
10

我有一個應用程序,它連接到互聯網並將數據存儲在SQL數據庫中。我使用iOS4進行測試,它完全可以正常工作。當我升級到新的版本,雖然,我得到一個NSInternalInconsistencyException,以此爲原因:'沒有數據庫通道可用'

「_obtainOpenChannel - NSSQLCore 0x951a640:沒有數據庫信道可用」

從我可以收集,我的數據庫正在被不應該被訪問的東西,雖然我不明白在哪裏或爲什麼。

任何人都可以幫助我找到並正確診斷我的問題嗎?

+0

您是否最終發現問題?我現在也在使用它(昨天更新到iOs5 ...),而且根本沒有任何信息可以找到。 – TheEye

回答

5

我發現這一個東西:

我得到了錯誤(一些其他中,看似隨機出現),而我是在不同的線程比管理方面是在創建一個訪問管理對象的關係。在iOS5(請參閱http://developer.apple.com/library/ios/#releasenotes/DataManagement/RN-CoreData/_index.html#//apple_ref/doc/uid/TP40010637)中同時訪問管理對象的過程中發生了一些更改 - 雖然文檔聲明默認行爲應該與iOS5之前一樣,但它顯然不是真的,我的代碼確實沒有問題地工作在iOS4.2中。

現在,我的解決方法是完成主線程中的所有關係訪問,將數據存儲在數組中,並通過該數組訪問我需要的數據。至少沒有更多的錯誤。我認爲這不是'好'的解決方案,因爲我應該(也將會)改變我同時訪問託管對象的方式,但是現在我不會立即改變它。

1

NSManagedObjectContext的此默認併發類型爲NSConfinementConcurrencyType,這意味着它只能由單個線程使用。從文檔:

您保證上下文不會被除您創建它之外的任何其他線程使用。

您可以改爲創建一個由私人隊列爲多線程應用支持的管理對象上下文:

[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType] 

從不同的線程使用管理對象方面,使用performBlock:(asyncronous)或performBlockAndWait: (同步),例如

__block NSArray *results; 
[[self managedObjectContext] performBlockAndWait:^{ 
    results = [[self managedObjectContext] executeFetchRequest:request error:&error]; 
}]; 
// do something with results 

該文檔說,您不需要使用創建託管對象上下文的線程中的塊API。

另一種選擇是爲每個線程創建單獨的託管對象上下文。

查看iOS 5 release notes瞭解更多信息。