How can I deallocate all references elements from an array?
Asked Answered
D

1

0

I'm trying to create a retrying mechanism for our network calls. I have created 2 classes. One a retry Class and another a Manager in case I wanted I can cancel all classes.

class Retry {
    var url: String
    var maxRetries: Int

    init (url: String, retryCount: Int){
        self.url = url
        self.maxRetries =  maxRetries
        poll()
        RetryManager.shared.add(self)
    }

    private func poll(){
        guard retryCount == 0 else{
            print("error")
        }
        getRequest()
    }

    private func getRequest(){
        // make network request
        // if no response is received poll again
    }


    func cancel(){
        maxRetries = 0
    }
}

Manager class

class RetryManager{

    static let sharedInstance = RetryManager()
    var retries : [Retry?] = []

    private init(){
    }

    func register(retry: Retry){
        retries.append(retry)
    }
    func remove(retry: Retry){
        retry.cancel() // XX; Do I also need this or just removing it is fine?
        retries = retries.filter({$0 !== retry})
    }

    func cancelAll(){

        retries.forEach({$0?.cancel()}) // ZZ; Do I also need this? or just removing them is fine?
        retries.removeAll()

    }

}

My Retry instances are to be used for making network calls.

My major question is about my cancel mechanism. Will doing a RetryManager.shared.cancelAll() suffice for deallocation? Or I need to run cancel or each cancel instance (ie XX, ZZ are also necessary)?

Currently everything works fine, but I'm not sure if I how it would work if I have multiple pointers...would I need to do:

for index..<retries.count{
retries[index] = nil
}

As far as I understand that won't help, it's same as doing retries.removeAll()

I also read In Swift, how do I set every element inside an array to nil? question but was told to open a new question

Deutero answered 10/4, 2017 at 21:41 Comment(0)
F
2

Not sure if I can answer your question, but I will try with my best understanding :).

Apple's Swift handbook on Automatic Reference Counting (ARC) covers your question very well.

Usually you don't need to have an array of optionals,

var retries = [Retry]() 
...
retries.removeAll()

will nicely remove all containing objects and delete the references to these objects. From your context presented above I do not understand why you need to declare an array of optionals. As you know Swift optionals under the hood are just a typed wrapper class Optional<Type>, which doesn't work around the memory allocation problem.

How does array reference objects?

The array will increase the contained objects' reference count by one, that is, a strong reference.

To ensure the objects in the array to be deallocated, one must make their reference count equal zero. Removing them from the array will do the trick, if nothing else is referencing the contained objects.

Beware of the reference cycle though. In your case, you should not hold reference to the retries array in Retry instance. Otherwise even if you set the retries array to nil, the array and its contained objects still have strong reference to each other, meaning their reference counts will never reduce to zero, causing memory leak.

Fiertz answered 10/4, 2017 at 23:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.