how to call deinit method within class definition in swift
Asked Answered
M

2

6

I want to define a method that can destroy the instance it belongs to when a variable in this class has increased to a certain value. I attempted to do something like following:

 var calledTimes = 0 //some other method would update this value

 func shouldDestroySelf(){
   if calledTimes == MAX_TIMES {
     denit
   }
 } 

But i would get error message saying "Expect '{' for deinitializers".

Is there anyway to self-destruct within the class?

Monometallic answered 29/1, 2016 at 4:7 Comment(4)
Its built in as a part of arc. self.deinit will destroy an object. But just make sure its not a viewController that is currently presented as this can cause issue.Pshaw
I guess you might be referring to this thread?Simar
hi Matthew self.deinit is not allowed to be called within the class definition.Monometallic
hey bipartite, no we are talking about two different things. I'm not trying to denit an instance by setting it = nil, I'm trying to define a method within the class that decide whether to self destruct or not.Monometallic
E
4

You can create a protocol which does the self destruction based on a certain criteria. Here's an example using a class

class SelfDestructorClass
{
    var calledTimes = 0
    let MAX_TIMES=5
    static var instancesOfSelf = [SelfDestructorClass]()

    init()
    {
        SelfDestructorClass.instancesOfSelf.append(self)
    }

    class func destroySelf(object:SelfDestructorClass)
    {
        instancesOfSelf = instancesOfSelf.filter {
            $0 !== object
        }
    }

    deinit {
        print("Destroying instance of SelfDestructorClass")
    }

    func call() {
        calledTimes += 1
        print("called \(calledTimes)")
        if calledTimes > MAX_TIMES {
            SelfDestructorClass.destroySelf(self)
        }
    }
}

You can derive your class from this class and then call call() on those object. The basic idea is to have the ownership of the object at one and only one place only and then detach the ownership when the criteria is met. The ownership in this case is a static array and detaching is removing it from the array. One important thing to note is that you have to use weak reference to the object wherever you are using it.

E.g.

class ViewController: UIViewController {

    weak var selfDestructingObject = SelfDestructorClass()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func countDown(sender:AnyObject?)
    {
        if selfDestructingObject != nil {
            selfDestructingObject!.call()
        } else {
            print("object no longer exists")
        }
    }
}
Ester answered 29/1, 2016 at 5:30 Comment(1)
this is really really smart man! wow. it reminds me of the old saying that any enginnering problem can be solved by adding one more layerMonometallic
B
4

You can not call deinit method. From Apple Docs: Deinitializers are called automatically, just before instance deallocation takes place. You are not allowed to call a deinitializer yourself.

You should set that instance to nil in order to destroy that instance provided that all references to that instance are broken .

Brach answered 29/1, 2016 at 5:7 Comment(0)
E
4

You can create a protocol which does the self destruction based on a certain criteria. Here's an example using a class

class SelfDestructorClass
{
    var calledTimes = 0
    let MAX_TIMES=5
    static var instancesOfSelf = [SelfDestructorClass]()

    init()
    {
        SelfDestructorClass.instancesOfSelf.append(self)
    }

    class func destroySelf(object:SelfDestructorClass)
    {
        instancesOfSelf = instancesOfSelf.filter {
            $0 !== object
        }
    }

    deinit {
        print("Destroying instance of SelfDestructorClass")
    }

    func call() {
        calledTimes += 1
        print("called \(calledTimes)")
        if calledTimes > MAX_TIMES {
            SelfDestructorClass.destroySelf(self)
        }
    }
}

You can derive your class from this class and then call call() on those object. The basic idea is to have the ownership of the object at one and only one place only and then detach the ownership when the criteria is met. The ownership in this case is a static array and detaching is removing it from the array. One important thing to note is that you have to use weak reference to the object wherever you are using it.

E.g.

class ViewController: UIViewController {

    weak var selfDestructingObject = SelfDestructorClass()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func countDown(sender:AnyObject?)
    {
        if selfDestructingObject != nil {
            selfDestructingObject!.call()
        } else {
            print("object no longer exists")
        }
    }
}
Ester answered 29/1, 2016 at 5:30 Comment(1)
this is really really smart man! wow. it reminds me of the old saying that any enginnering problem can be solved by adding one more layerMonometallic

© 2022 - 2024 — McMap. All rights reserved.