我正在尝试使用UIAlertController处理错误,并且可以选择重试导致错误的代码。我想出了这个巨大的混乱,它实际上是有效的:
func handleError(_ closure: @escaping () throws -> Void) {
do {
try closure()
} catch {
print(error)
let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
let retry = UIAlertAction(title: "Retry", style: .default, handler: {(_: UIAlertAction) in self.handleError(closure)})
alert.addAction(retry)
let cancel = UIAlertAction(title: "Cancel", style: .cancel)
alert.addAction(cancel)
present(alert, animated: true)
}
}
然而,仅仅看一下,看起来它会导致更多错误而不是阻止它们。有什么办法可以让这个简单或不那么混乱吗?我无法理解为什么我需要@escaping部分(但编译器告诉我我这样做),或者为什么我需要为UIAlertAction闭包提供一个空白参数。
我需要一些保证,这对解决方案来说并不算太糟糕。
答案 0 :(得分:2)
@escaping的想法让你意识到你的闭包将在异步调用中执行。以这种方式思考:假设你必须调用一个你自己没有开发的函数,并且必须通过一个闭包来实现它。现在假设您期望闭包将作为同步调用执行。你怎么知道它是否只用作同步通话? Swift使用@escaping注释来为您提供此保证。如果在任何异步调用中使用该函数,则必须在函数签名中通知此函数。在您的情况下,您将函数传递给将等待用户操作来调用闭包的AlertController。
关于空白参数,实际上这不是一个空白参数,它是一个函数签名。在这里,您告诉编译器您将接收函数作为参数,并且此函数没有参数并且不返回任何内容,但可以抛出异常。在swift中,函数有类型。接收字符串作为参数并返回布尔值的函数的类型为<div class="page_menu_wrapper">
<nav class='page-menu'>
<ul>
<li>
<a href='/'><img height='70' src='http://xf.com/new/logo.png' width='171' /></a>
</li>
<li><a href='about.php'><span itemprop='name'>About</span></a></li>
<li><a href='contact.php'><span itemprop='name'>Contact</span></a></li>
<li><a href='privacy.php'><span itemprop='name'>Privacy</span></a></li>
<li><a href='sitemap.php'><span itemprop='name'>Sitemap</span></a></li>
<li><a href='iklan.php'><span itemprop='name'>Iklan</span></a></li>
<li>
<form class="searchform">
<input class="searchfield" type="text" value="Search..." onfocus="if (this.value == 'Search...') {this.value = '';}" onblur="if (this.value == '') {this.value = 'Search...';}" />
<input class="searchbutton" type="button" value="Go" />
</form>
</li>
</ul>
</nav>
</div>
。使用empty参数,您将定义将作为参数接受的函数的类型,在这种情况下,您的函数类型为(String)-> Bool
,可以汇总为() -> ()
,表示:一个函数没有争论,也没有回报。
您可以在swift here中找到有关函数类型的更多信息。
顺便说一句,我认为你的代码是正确的。我没有看到任何问题,但为了给你一个正确的答复我必须知道你的关闭将会是什么。