- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
swift 4.2,Xcode 10.1
在我正在处理的订单处理应用程序中,用户可以搜索已处理或提交的订单。发生这种情况时,它将检查是否有订单缓存,如果没有,它将使用异步 API 请求重新填充该缓存,然后再次检查缓存。
重新填充缓存的函数是一个私有(private)静态函数,它接受一个转义完成处理程序。每当我过去使用那个完成处理程序时,我所要做的就是在函数调用的末尾添加一个闭包。这是在我被指示尽可能缓存所有数据之前,并且只使用 API 来重新填充该缓存之前。从那时起,这个函数就变成了私有(private)函数,因为除了在这个类中,再也不需要从任何地方直接调用 API。
现在,当我将闭包直接放在函数调用之后时,它给我一个错误,基本上说我传递的是 @nonescaping 闭包而不是 @escaping 闭包:
"Cannot invoke 'getAndCacheAPIData' with an argument list of type '(type: Codable.Type, (String?) -> Void)', Expected an argument list of type '(type: CodableClass.Type, @escaping (String?) -> Void)'"
我以前从来没有明确声明一个闭包是@escaping,这似乎是不可能的。我怀疑因为该函数既是私有(private)的又是静态的,所以闭包被推断为@escaping 的方式存在某种问题。我超出了我的深度。我可以尝试将静态类转换为单例,但由于一个错误,我对重构一堆工作代码犹豫不决,直到我完全确定更改将解决问题,而我正在尝试做的是除非我改变我的方法,否则这是不可能的。
代码如下:
public static func fillSearchResultArray<ManagedClass: NSManagedObject>(query:String, parameters:[String], with type: ManagedClass.Type, completionHandler: @escaping (String?)->Void)
{
let codableType:Codable.Type
switch type
{
case is ClientTable.Type:
codableType = ClientData.self
case is OrderTable.Type:
codableType = OrderData.self
case is ProductTable.Type:
codableType = ProductData.self
default:
completionHandler("Unrecognized type.")
return
}
let fetchedData:[ManagedClass]
do
{
fetchedData = try PersistenceManager.shared.fetch(ManagedClass.self)
}
catch
{
completionHandler(error.localizedDescription)
return
}
if fetchedData.isEmpty
{
AppNetwork.getAndCacheAPIData(type: codableType)//error here
{(firstErrorString) in
//move search array data to the cache
if firstErrorString.exists
{
completionHandler(error)
}
else
{
AppNetwork.fillSearchResultArray(query: query, parameters: parameters, type: type)
{ errorString in
completionHandler(errorString)
}
}
}
return
}
else
{ ...
被调用函数的签名:
private static func getAndCacheAPIData <CodableClass: Any & Codable>(type:CodableClass.Type, completionHandler: @escaping (String?)->Void)
为什么 swift 将此闭包推断为默认的 @nonescaping 而之前它总是将其推断为 @escaping?
最佳答案
问题与闭包无关,与静态无关,与私有(private)无关。它与类型参数有关。您不能调用此方法:
private static func getAndCacheAPIData <CodableClass: Any & Codable>(type:CodableClass.Type, completionHandler: @escaping (String?)->Void)
使用类型为 Codable.Type
的变量.您传递的类型值必须是在编译时已知的具体类型。如果你想传递一个变量,你不能使用泛型。它必须是:
private static func getAndCacheAPIData(type: Codable.Type, completionHandler: @escaping (String?)->Void)
或者,您可以将其称为:
AppNetwork.getAndCacheAPIData(type: Int.self) {(firstErrorString) in ... }
或其他一些在编译时已知的类型。
可能你真正想要的是这样的:
let completion: (String?) -> Void = {(firstErrorString) in ... }
switch ... {
case ...:
AppNetwork.getAndCacheAPIData(type: Int.self, completion: completion)
case ...:
AppNetwork.getAndCacheAPIData(type: String.self, completion: completion)
...
基本问题是协议(protocol)不符合自身,因此类型为 Codable.Type
的变量不满足 : Codable
要求。这归结为您不能只调用的相同原因:
AppNetwork.getAndCacheAPIData(type: Codable.self) {...}
或者,您可以这样重构它:
private static func handleAPI<CodableClass: Codable>(type: CodableClass.Type) {
getAndCacheAPIData(type: type.self) { _ in ... the completion handler ..}
}
switch ... {
case ...:
AppNetwork.handleAPI(type: Int.self)
case ...:
AppNetwork.handleAPI(type: String.self)
...
旁注:Any &
在这里是没有意义的。你只是说 <CodableClass: Codable>
.
关于当完成处理程序明确使用@escaping 时,Swift 将完成处理程序闭包推断为默认的@nonescaping 而不是@escaping,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55011737/
SQLite、Content provider 和 Shared Preference 之间的所有已知区别。 但我想知道什么时候需要根据情况使用 SQLite 或 Content Provider 或
警告:我正在使用一个我无法完全控制的后端,所以我正在努力解决 Backbone 中的一些注意事项,这些注意事项可能在其他地方更好地解决......不幸的是,我别无选择,只能在这里处理它们! 所以,我的
我一整天都在挣扎。我的预输入搜索表达式与远程 json 数据完美配合。但是当我尝试使用相同的 json 数据作为预取数据时,建议为空。点击第一个标志后,我收到预定义消息“无法找到任何内容...”,结果
我正在制作一个模拟 NHL 选秀彩票的程序,其中屏幕右侧应该有一个 JTextField,并且在左侧绘制弹跳的选秀球。我创建了一个名为 Ball 的类,它实现了 Runnable,并在我的主 Draf
这个问题已经有答案了: How can I calculate a time span in Java and format the output? (18 个回答) 已关闭 9 年前。 这是我的代码
我有一个 ASP.NET Web API 应用程序在我的本地 IIS 实例上运行。 Web 应用程序配置有 CORS。我调用的 Web API 方法类似于: [POST("/API/{foo}/{ba
我将用户输入的时间和日期作为: DatePicker dp = (DatePicker) findViewById(R.id.datePicker); TimePicker tp = (TimePic
放宽“邻居”的标准是否足够,或者是否有其他标准行动可以采取? 最佳答案 如果所有相邻解决方案都是 Tabu,则听起来您的 Tabu 列表的大小太长或您的释放策略太严格。一个好的 Tabu 列表长度是
我正在阅读来自 cppreference 的代码示例: #include #include #include #include template void print_queue(T& q)
我快疯了,我试图理解工具提示的行为,但没有成功。 1. 第一个问题是当我尝试通过插件(按钮 1)在点击事件中使用它时 -> 如果您转到 Fiddle,您会在“内容”内看到该函数' 每次点击都会调用该属
我在功能组件中有以下代码: const [ folder, setFolder ] = useState([]); const folderData = useContext(FolderContex
我在使用预签名网址和 AFNetworking 3.0 从 S3 获取图像时遇到问题。我可以使用 NSMutableURLRequest 和 NSURLSession 获取图像,但是当我使用 AFHT
我正在使用 Oracle ojdbc 12 和 Java 8 处理 Oracle UCP 管理器的问题。当 UCP 池启动失败时,我希望关闭它创建的连接。 当池初始化期间遇到 ORA-02391:超过
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve
引用这个plunker: https://plnkr.co/edit/GWsbdDWVvBYNMqyxzlLY?p=preview 我在 styles.css 文件和 src/app.ts 文件中指定
为什么我的条形这么细?我尝试将宽度设置为 1,它们变得非常厚。我不知道还能尝试什么。默认厚度为 0.8,这是应该的样子吗? import matplotlib.pyplot as plt import
当我编写时,查询按预期执行: SELECT id, day2.count - day1.count AS diff FROM day1 NATURAL JOIN day2; 但我真正想要的是右连接。当
我有以下时间数据: 0 08/01/16 13:07:46,335437 1 18/02/16 08:40:40,565575 2 14/01/16 22:2
一些背景知识 -我的 NodeJS 服务器在端口 3001 上运行,我的 React 应用程序在端口 3000 上运行。我在 React 应用程序 package.json 中设置了一个代理来代理对端
我面临着一个愚蠢的问题。我试图在我的 Angular 应用程序中延迟加载我的图像,我已经尝试过这个2: 但是他们都设置了 src attr 而不是 data-src,我在这里遗漏了什么吗?保留 d
我是一名优秀的程序员,十分优秀!