neoneye
neoneye

Reputation: 52221

Post-creation callback: How to run code immediately after ctor?

I wonder if I can get a callback after init(), or perhaps before deinit().

I have this repeating pattern in my code. First init() is run. Next fire() function is run.

class ParentViewController: UIViewController {
    @IBAction func redButtonAction(sender: AnyObject) {
        PickedColorEvent(color: UIColor.redColor(), name: "RED").fire()
    }
    @IBAction func greenButtonAction(sender: AnyObject) {
        PickedColorEvent(color: UIColor.greenColor(), name: "GREEN").fire()
    }
    @IBAction func blueButtonAction(sender: AnyObject) {
        PickedColorEvent(color: UIColor.blueColor(), name: "BLUE").fire()
    }
    @IBAction func resetButtonAction(sender: AnyObject) {
        ResetEvent().fire()
    }
}

Desired code, without calling the fire() function. I want it to autofire after creation. My code always run on the main-thread, so I guess I could use a one-shot timer for this. However I'm looking for a solution without timers.

class ParentViewController: UIViewController {
    @IBAction func redButtonAction(sender: AnyObject) {
        PickedColorEvent(color: UIColor.redColor(), name: "RED")
    }
    @IBAction func greenButtonAction(sender: AnyObject) {
        PickedColorEvent(color: UIColor.greenColor(), name: "GREEN")
    }
    @IBAction func blueButtonAction(sender: AnyObject) {
        PickedColorEvent(color: UIColor.blueColor(), name: "BLUE")
    }
    @IBAction func resetButtonAction(sender: AnyObject) {
        ResetEvent()
    }
}

Is it possible to get rid of the fire() function?

Update 1 (thanks feedback from @luk2302)

The event classes inherit from a protocol. I could change the protocol to a class or a struct, and call fire() within the base class. However then I decide wether the subclasses can be struct or class.

When just invoking ResetEvent() without using the result, then I get the Result of initializer is unused. I wish there was a reserved keyword for suppressing that warning.

Upvotes: 0

Views: 290

Answers (1)

user3441734
user3441734

Reputation: 17572

you can use fire function after you initialised all stored properties as you can call any other function defined in your class and / or struct

protocol P {}
extension P {
    func fire(s: String) {
        print("fire from \(s)")
    }
}
class C:P {
    var i: Int
    init(i:Int) {
        self.i = i
        foo()
        fire("class init i: \(self.i)")
    }
    deinit {
        fire("class deinit i: \(i)")
    }
    func foo() {
        i += 1
    }
}

struct S:P {
    var i: Int
    init(i: Int){
        self.i = i
        foo()
        fire("struct init i: \(self.i)")
    }
    mutating func foo() {
        i += 10
    }

}

C(i: 5)
S(i: 1)

/*
fire from class init i: 6
fire from struct init i: 11
fire from class deinit i: 6
*/

If you want to avoid compiler warning "Result of initializer is unused", just use next syntax

_ = C(i: 5)
_ = S(i: 1)

Upvotes: 1

Related Questions