I have a class that implements the XMLParserDelegate
protocol and during initialisation it gets a string and a completion handler as the arguments. I'm trying to call completion handler after parsing of the string, but the XMLParserDelegate
methods are not being reached because of deallocation of the class.
class MyXMLParser: NSObject, XMLParserDelegate {
private (set) var parser: XMLParser?
private (set) var completion: ((String?) -> Void)?
public init(_ xml: String, _ completion: @escaping ((String?) -> Void)) {
let data = xml.data(using: String.Encoding.utf8)
self.parser = XMLParser(data: data ?? Data())
self.completion = completion
self.parser?.delegate = self
self.parser?.parse()
}
deinit {
// Being called before Parser methods
}
// MARK: - Parser delegate methods
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
// Custom implementation
}
func parserDidEndDocument(_ parser: XMLParser) {
// Custom implementation
self.completion?("Test")
}
func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
self.completion?(nil)
}
}
And I'm calling it the following way:
func someFunc() {
let parser = MyXMLParser(someXMLString) { text in
// Custom implementation
}
}
I want the closure to stay alive until it gets the value, instead of getting deinitialized after its local scope inside of the function has been ended. Great example of what I want to achieve is UIView.animate()
completion block that does not get deallocated even if it is located inside of some function.