CoreDataでデータベースを取得する関数を作成しました。この関数はクロージャを実行し、performBackgroundTask
を実行してデータをフェッチします。次に、結果をクロージャに渡して実行します。私はcontext
を交換する場合CoreDataのperformBackgroundTaskメソッドがクラッシュする
func fetch<T>(fetchRequest: NSFetchRequest<T>, keyForOrder: String? = nil, format: String? = nil, keyword: String? = nil, handler: (([T]?)->Void)? = nil) where T:NSManagedObject, T: NSFetchRequestResult {
AppDelegate.persistentContainer.performBackgroundTask{(context: NSManagedObjectContext) in
if let format = format?.trimmingCharacters(in: .whitespacesAndNewlines),
!format.isEmpty,
let keyword = keyword?.trimmingCharacters(in: .whitespacesAndNewlines),
!keyword.isEmpty {
fetchRequest.predicate = NSPredicate(format: format, keyword)
}
if let keyForOrder = keyForOrder {
fetchRequest.sortDescriptors = [NSSortDescriptor(key: keyForOrder, ascending: true)]
}
guard let cats = try? context.fetch(fetchRequest) else { // crash
return
}
context.performAndWait(){ // crash
if let handler = handler {
handler(cats)
}
}
}
}
しかし:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
static var persistentContainer: NSPersistentContainer {
return (UIApplication.shared.delegate as! AppDelegate).persistentContainer
}
static var viewContext: NSManagedObjectContext {
return persistentContainer.viewContext
}
// ...
}
次はcontext
を使用して墜落した私が書いた機能(ない方法)である:私は簡単にviewContext
にアクセスするため 私はAppDelegate
に静的プロパティを書きましたAppDelegate.viewContext
で、機能がクラッシュしなくなります。
func fetch<T>(fetchRequest: NSFetchRequest<T>, keyForOrder: String? = nil, format: String? = nil, keyword: String? = nil, handler: (([T]?)->Void)? = nil) where T:NSManagedObject, T: NSFetchRequestResult {
AppDelegate.persistentContainer.performBackgroundTask{(context: NSManagedObjectContext) in
if let format = format?.trimmingCharacters(in: .whitespacesAndNewlines),
!format.isEmpty,
let keyword = keyword?.trimmingCharacters(in: .whitespacesAndNewlines),
!keyword.isEmpty {
fetchRequest.predicate = NSPredicate(format: format, keyword)
}
if let keyForOrder = keyForOrder {
fetchRequest.sortDescriptors = [NSSortDescriptor(key: keyForOrder, ascending: true)]
}
guard let cats = try? AppDelegate.viewContext.fetch(fetchRequest) else { // crash
return
}
AppDelegate.viewContext.performAndWait(){ // crash
if let handler = handler {
handler(cats)
}
}
}
}
を何まったく同じですか?
ありがとうございました。
条件は正常です。 Xcodeが示すように、viewContextだけがクラッシュします。アプリのサイズが大きくなるにつれ、私はperformbacktaskを削除しました。私は常にUIのスタッフのメインキューに渡す必要があります。コンテキストを使用すると、performbacktaskが提供するコンテキストがクラッシュするという点が分かりません。 –
performBackgroundTaskによって提供されたコンテキストでのフェッチはクラッシュしません。何か間違っているので、コード内でクラッシュします。コードには多くの問題があり、クラッシュレポートを見たことがないので、クラッシュの原因を正確に突き止めるのは難しいです。しかし、私の最高のゲストは、実際のクラッシュはコンテキストが処理された後にバックグラウンドコンテキストのmanagedObjectsにアクセスすることによるものです(上記のリストの2番目の項目)。 –