如何在Swift中的函数中的return语句之后运行代码?

时间:2021-11-01 16:25:52

Consider the following code:

请考虑以下代码:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    let validator:NSPredicate = NSPredicate(format:"SELF MATCHES %@","[A-Za-z0-9- ]+")
    if(validator.evaluateWithObject(string) || string == "" /* i.e. backspace */) {
        self.process(textField)
        return true
    }
    else {
        return false
    }
}

I want to actually run self.process(textField) AFTER the return statement, because before it, the text in the textField has not actually changed yet. This led me to wonder, why can't I just execute some code after the return statement? Why do functions always stop when the return statement happens?

我想在return语句之后实际运行self.process(textField),因为在它之前,textField中的文本还没有实际更改。这让我想知道,为什么我不能只在return语句后执行一些代码?为什么函数总是在return语句发生时停止?

I realize that's traditionally what return means, but is there an alternative? Like, is there a way to return a value from a function and then still keep going?

我意识到传统意义上的回报意味着什么,但还有另一种选择吗?比如,有没有办法从函数中返回一个值然后仍然继续?

On the one hand this seems like a stupid question, but on the other hand, I feel like I can't be the first person to ever want to do this. It would be good enough if I could fire off something to run on the next cycle of the run loop, so maybe there's something in GCD that would help me.

一方面,这似乎是一个愚蠢的问题,但另一方面,我觉得我不能成为第一个想要做到这一点的人。如果我可以在运行循环的下一个循环中触发某些东西就足够了,所以GCD中的某些内容可能对我有帮助。

4 个解决方案

#1


6  

Since Swift 2.0 we have the keyword called "defer". This keyword allows us to specify a block of code that will be executed when the current function ends, for cleanup actions or other needs. This block of code will be deferred until the last statement is executed, no matter if it's a return statement or any other.

从Swift 2.0开始,我们有一个名为“defer”的关键字。此关键字允许我们指定当前函数结束时将执行的代码块,用于清理操作或其他需要。这段代码将被推迟到执行最后一条语句,无论它是返回语句还是其他任何语句。

Here's how you can use it:

以下是如何使用它:

func anyFunction(someParameter: Int) -> Int {

    // Some code

    return SomeValue

    defer {

        // This block will be executed at the end of this function and after all statements.

    }

}

The position of the "defer" block doesn't have to be at the end of the function it could be anywhere within the curly braces.

“延迟”块的位置不必位于函数的末尾,它可以是大括号内的任何位置。

#2


2  

I think you need to move your process code to another function.

我认为您需要将您的流程代码移动到另一个功能。

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
    print("view loaded")
    textField.addTarget(self,
        action: "textFieldDidChange:", forControlEvents: .EditingChanged)
}


func textFieldDidChange(textField: UITextField){
    print("text changed: \(theTextField.text)")
    self.process(textField)
}

#3


0  

There is no language primitive to run arbitrary code after a return statement. No language provides this. However you can always use closures to embed and sequence code flow; like a completion handler.

在return语句之后没有语言原语来运行任意代码。没有语言提供这个。但是,您始终可以使用闭包来嵌入和排序代码流;像完成处理程序。

In some cases you may want to use willSet and/or didSet. Imagine having a String property that is a backing store for your text field. If the string is validated, then you write to the backing store. That will then trigger willSet which can run your process code and update the textField directly depending on the results.

在某些情况下,您可能希望使用willSet和/或didSet。想象一下,String属性是文本字段的后备存储。如果验证了字符串,则写入后备存储。然后,它将触发willSet,它可以运行您的过程代码并根据结果直接更新textField。

#4


0  

Defer injections should be at the reachable statements of the code, otherwise they will not be executed at the end of the block. Basically, its the main idea of defer.

延迟注入应该在代码的可访问语句中,否则它们将不会在块的末尾执行。基本上,它是推迟的主要思想。

#1


6  

Since Swift 2.0 we have the keyword called "defer". This keyword allows us to specify a block of code that will be executed when the current function ends, for cleanup actions or other needs. This block of code will be deferred until the last statement is executed, no matter if it's a return statement or any other.

从Swift 2.0开始,我们有一个名为“defer”的关键字。此关键字允许我们指定当前函数结束时将执行的代码块,用于清理操作或其他需要。这段代码将被推迟到执行最后一条语句,无论它是返回语句还是其他任何语句。

Here's how you can use it:

以下是如何使用它:

func anyFunction(someParameter: Int) -> Int {

    // Some code

    return SomeValue

    defer {

        // This block will be executed at the end of this function and after all statements.

    }

}

The position of the "defer" block doesn't have to be at the end of the function it could be anywhere within the curly braces.

“延迟”块的位置不必位于函数的末尾,它可以是大括号内的任何位置。

#2


2  

I think you need to move your process code to another function.

我认为您需要将您的流程代码移动到另一个功能。

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
    print("view loaded")
    textField.addTarget(self,
        action: "textFieldDidChange:", forControlEvents: .EditingChanged)
}


func textFieldDidChange(textField: UITextField){
    print("text changed: \(theTextField.text)")
    self.process(textField)
}

#3


0  

There is no language primitive to run arbitrary code after a return statement. No language provides this. However you can always use closures to embed and sequence code flow; like a completion handler.

在return语句之后没有语言原语来运行任意代码。没有语言提供这个。但是,您始终可以使用闭包来嵌入和排序代码流;像完成处理程序。

In some cases you may want to use willSet and/or didSet. Imagine having a String property that is a backing store for your text field. If the string is validated, then you write to the backing store. That will then trigger willSet which can run your process code and update the textField directly depending on the results.

在某些情况下,您可能希望使用willSet和/或didSet。想象一下,String属性是文本字段的后备存储。如果验证了字符串,则写入后备存储。然后,它将触发willSet,它可以运行您的过程代码并根据结果直接更新textField。

#4


0  

Defer injections should be at the reachable statements of the code, otherwise they will not be executed at the end of the block. Basically, its the main idea of defer.

延迟注入应该在代码的可访问语句中,否则它们将不会在块的末尾执行。基本上,它是推迟的主要思想。