Swift @转义和完成处理程序 [英] Swift @escaping and Completion Handler

查看:81
本文介绍了Swift @转义和完成处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图更准确地理解Swift的关闭。



但是 @转义完成处理程序太难理解了



我搜索了很多Swift帖子和官方文档,但我觉得还不够。



这是官方文档的代码示例

  var完成处理程序:[()-> Void] = [] 

func someFunctionWithEscapingClosure(completionHandler:@escaping()-> Void){
completeHandlers.append(completionHandler)
}

func someFunctionWithNoneescapingClosure(closure:()-> Void){
closure()
}

class SomeClass {
var x :Int = 10
func doSomething(){
someFunctionWithEscapingClosure {
self.x = 100
//尚未执行
}
someFunctionWithNoneescapingClosure {
x = 200
}
}
}

let instance = SomeClass()
instance.doSomething()
print(instance.x)

completionHandlers.first?()
print(instance.x)

我听说使用 @转义



第一个用于存储闭包,第二个用于异步操作。



以下是我的问题



首先,如果执行 doSomething ,则 someFunctionWithEscapingClosure 将使用闭包参数执行,并且该闭包将保存在全局变量数组中。



我认为闭包是{self.x = 100}



自我如何保存在全局变量 completionHandlers 中的{self.x = 100}中的可以连接到 instance SomeClass 的对象?



第二,我理解 someFunctionWithEscapingClosure 这样。



将局部变量闭包 completionHandler 存储到全局变量'completionHandlers 我们使用 @ escaping`关键字!



没有 @escaping 关键字 someFunctionWithEscapingClosure 返回,局部变量 completionHandler 将从内存中删除



@转义被保留



是不是?



最后,我只是想知道这种语法的存在



也许这是一个非常基本的问题。



如果我们希望某些功能在某些特定功能之后执行。为什么我们不只在特定的函数调用后才调用某些函数?



使用上述模式与使用转义的回调函数有什么区别?

解决方案

快速完成处理程序转义&不转义:


如Bob Lee在其博客文章。


再增加一点,每个ios开发人员都需要了解:


  1. 转义闭包:转义闭包是在将函数传递给返回值之后调用的闭包。换句话说,
    的寿命比传递给它的函数要长。

  2. 非转义的闭包:在传递的函数中调用的闭包进入,即在返回之前。


I am trying to understand 'Closure' of Swift more precisely.

But @escaping and Completion Handler are too difficult to understand

I searched many Swift postings and official documents, but I felt it was still not enough.

This is the code example of official documents

var completionHandlers: [()->Void] = []

func someFunctionWithEscapingClosure(completionHandler: @escaping ()->Void){
    completionHandlers.append(completionHandler)
}

func someFunctionWithNoneescapingClosure(closure: ()->Void){
    closure()
}

class SomeClass{
    var x:Int = 10
    func doSomething(){
        someFunctionWithEscapingClosure {
            self.x = 100
            //not excute yet
        }
        someFunctionWithNoneescapingClosure {
            x = 200
        }
    }
}

let instance = SomeClass()
instance.doSomething()
print(instance.x)

completionHandlers.first?() 
print(instance.x)

I heard that there are two ways and reasons using @escaping

First is for storing a closure, second is for Async operating purposes.

The following are my questions:

First, if doSomething executes then someFunctionWithEscapingClosure will executing with closure parameter and that closure will be saved in global variable array.

I think that closure is {self.x = 100}

How self in {self.x = 100} that saved in global variable completionHandlers can connect to instance that object of SomeClass ?

Second, I understanding someFunctionWithEscapingClosure like this.

To store local variable closure completionHandler to global variable 'completionHandlerswe using@escaping` keyword!

without @escaping keyword someFunctionWithEscapingClosure returns, local variable completionHandler will remove from memory

@escaping is keep that closure in the memory

Is this right?

Lastly, I just wonder about the existence of this grammar.

Maybe this is a very rudimentary question.

If we want some function to execute after some specific function. Why don't we just call some function after a specific function call?

What are the differences between using the above pattern and using an escaping callback function?

解决方案

Swift Completion Handler Escaping & Non-Escaping:

As Bob Lee explains in his blog post Completion Handlers in Swift with Bob:

Assume the user is updating an app while using it. You definitely want to notify the user when it is done. You possibly want to pop up a box that says, "Congratulations, now, you may fully enjoy!"

So, how do you run a block of code only after the download has been completed? Further, how do you animate certain objects only after a view controller has been moved to the next? Well, we are going to find out how to design one like a boss.

Based on my expansive vocabulary list, completion handlers stand for

Do stuff when things have been done

Bob’s post provides clarity about completion handlers (from a developer point of view it exactly defines what we need to understand).

@escaping closures:

When one passes a closure in function arguments, using it after the function’s body gets executed and returns the compiler back. When the function ends, the scope of the passed closure exist and have existence in memory, till the closure gets executed.

There are several ways to escaping the closure in containing function:

  • Storage: When you need to store the closure in the global variable, property or any other storage that exist in the memory past of the calling function get executed and return the compiler back.

  • Asynchronous execution: When you are executing the closure asynchronously on despatch queue, the queue will hold the closure in memory for you, can be used in future. In this case you have no idea when the closure will get executed.

When you try to use the closure in these scenarios the Swift compiler will show the error:

For more clarity about this topic you can check out this post on Medium.

Adding one more points , which every ios developer needs to understand :

  1. Escaping Closure : An escaping closure is a closure that’s called after the function it was passed to returns. In other words, it outlives the function it was passed to.
  2. Non-escaping closure : A closure that’s called within the function it was passed into, i.e. before it returns.

这篇关于Swift @转义和完成处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆