簡體   English   中英

NSManagedObjectContext Async/Await perform(schedule:_:)' 僅在 iOS 15.0 或更高版本中可用

[英]NSManagedObjectContext Async/Await perform(schedule:_:)' is only available in iOS 15.0 or newer

我正在開發一個仍然支持 iOS 13 並且需要使用 CoreData 獲取一些數據的應用程序。

這就是我通常會這樣做的方式

context.perform({
  let results = try context.fetch(request)
})

現在 Xcode 13 和 async/await 可以返回到 iOS 13 我得到一個編譯器錯誤

'perform(schedule:_:)' 僅在 iOS 15.0 或更高版本中可用

跳轉到定義顯示 CoreData 中的以下新 API

@available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)
extension NSManagedObjectContext {

    public func performAndWait<T>(_ block: () throws -> T) rethrows -> T

    public func perform<T>(schedule: NSManagedObjectContext.ScheduledTaskType = .immediate, _ block: @escaping () throws -> T) async rethrows -> T
}

當注釋掉 Block 中的代碼時,它會跳轉到 CoreData/NSManagedObjectContext 中的舊 API

/* asynchronously performs the block on the context's queue.  Encapsulates an autorelease pool and a call to processPendingChanges */
@available(iOS 5.0, *)
open func perform(_ block: @escaping () -> Void)

為什么編譯器 select 是perform的新變體,如何強制它使用舊的非異步版本?

編輯:這是一個演示問題的最小示例項目: https://github.com/iv-mexx/CoreDataRepro

感謝@Cy-4AH,我想通了!

問題是,我正在做所有事情,包括在一個大的do / catch塊中執行context.perform

do {
    ...
    context.perform({
      let results = try context.fetch(request)
    })
    ...
} catch { 
    ...
}

新的perform擴展方法現在被標記為rethrows而舊的不是,因此在 perform 塊中有一個 throwing 方法的事實意味着編譯器選擇了 rethrowing perform ,它僅在 iOS >= 15 上可用。

@Cy-4AH 建議使用try? 而不是try which works 因為錯誤就在那里被捕獲,而不是強制使用rethrowing方法。

另一種解決方案是將do/catch移動到perform內:

context.perform({
  do {
    let results = try context.fetch(request)
  } catch { 
    ...
  }
})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM