Below, there are one protocol which has two closure variables and a functions. And there is also a class conforming to the protocol.
import Foundation
protocol TestProtocol: class {
var firstClosure: () -> () { get set }
var secondClosure: () -> () { get set }
func testFunction()
}
extension TestProtocol {
func testFunction() {
_ = firstClosure
_ = secondClosure
}
}
class A: TestProtocol {
var firstClosure: () -> ()
var secondClosure: () -> ()
var number = 0
init() {
print(number)
firstClosure = {
self.number = 1
}()
print(number)
secondClosure = {
self.number = 2
}()
print(number)
testFunction()
print(number)
}
}
let a = A()
My expected result is 0, 0, 0, 2. But, when I define closure variable, the closure variable execute immediately. What should I do?
The issue is that you aren't defining closures, you're defining Void
s due to the fact that you execute the closures right after defining them by writing ()
after the closure. The type of firstClosure
and secondClosure
are both Void
, which is a typealias for ()
. If you wanted to declare a closure that takes no input arguments and returns no value (or rather returns Void
), you need to declare it as () -> ()
.
protocol TestProtocol: class {
var firstClosure: () -> () { get set }
var secondClosure: () -> () { get set }
func testFunction()
}
extension TestProtocol {
func testFunction() {
firstClosure()
secondClosure()
}
}
You should also modify your conforming class to directly set the closure's instead of setting them in the initializer and not to call a function with side effects (testFunction
) in the initializer, but rather call it when you actually need it after initialisation. You need to declare your closures as lazy
, since they access self
.
class A: TestProtocol {
var number = 0
lazy var firstClosure: () -> Void = {
self.number = 1
}
lazy var secondClosure: () -> Void = {
self.number = 2
}
}
A().testFunction()