iosswiftxcodeiphone-developer-program

Why I cannot change the value of variable inside Timer.scheduledTimer function?


When I try to change the value of accumulatedTime inside Timer function, the value of accumulatedTime retains unchanged.

import UIKit

class WelcomeViewController: UIViewController {

    @IBOutlet weak var titleLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        titleLabel.text = ""
        var accumulatedTime = 0.0
        let logo = "Hello World"
        for letter in logo {
            Timer.scheduledTimer(withTimeInterval: accumulatedTime*0.1, repeats: false) { (timer) in
                self.titleLabel.text?.append(letter)
                accumulatedTime += 1  // increase the value of variable inside block function
            }
            print(accumulatedTime)
        }
    }
}

// Output is 0.0, 0.0, 0.0, 0.0, 0.0, 0.0...

But if I move the "accumulatedTime += 1" outside the block function of Timer.scheduledTimer, the value of accumulatedTime can be changed again.

import UIKit

class WelcomeViewController: UIViewController {

    @IBOutlet weak var titleLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        titleLabel.text = ""
        var accumulatedTime = 0.0
        let logo = "Hello World"
        for letter in logo {
            Timer.scheduledTimer(withTimeInterval: accumulatedTime*0.1, repeats: false) { (timer) in
                self.titleLabel.text?.append(letter)
            }
            accumulatedTime += 1 // increase the value of variable outside block function
            print(accumulatedTime)
        }
    }
}

// Output is 1.0, 2.0, 3.0, 4.0, 5.0...

I am curious why I cannot change the value of local variable inside the block function of Timer.scheduledTimer, Can you guys help me to understand the inside logic of this.. Thank you


Solution

  • for letter in logo {
                Timer.scheduledTimer(withTimeInterval: accumulatedTime*0.1, repeats: false) { (timer) in
                    self.titleLabel.text?.append(letter)
                    accumulatedTime += 1  // increase the value of variable inside block function
                }
                print(accumulatedTime)
            }
    

    Print statement runs before closure execute ... thats why they are all 0 .. because its not get SET when your print code execute in for loop ... take print statement inside closure

    for letter in logo {
                    Timer.scheduledTimer(withTimeInterval: accumulatedTime*0.1, repeats: false) { (timer) in
                        self.titleLabel.text?.append(letter)
                        accumulatedTime += 1  // increase the value of variable inside block function
                        print(accumulatedTime)// print 1,2,3 .. 11
                    }
    
                }
    

    in Closure its value is changing ... and you can access changed value when closure execute ..