gpt4 book ai didi

ios - 允许完成处理程序在创建它的本地范围内存活

转载 作者:行者123 更新时间:2023-11-28 07:30:49 25 4
gpt4 key购买 nike

我有一个实现 XMLParserDelegate 协议(protocol)的类,在初始化期间它获取一个字符串和一个完成处理程序作为参数。我试图在解析字符串后调用完成处理程序,但由于类的重新分配,未访问 XMLParserDelegate 方法。

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)
}

}

我是这样调用它的:

func someFunc() {
let parser = MyXMLParser(someXMLString) { text in
// Custom implementation
}
}

我希望闭包在获取值之前保持事件状态,而不是在函数内部的局部作用域结束后取消初始化。我想要实现的一个很好的例子是 UIView.animate() 完成 block ,即使它位于某个函数内部也不会被释放。

最佳答案

您需要将 MyXMLParser 存储在局部变量以外的其他地方。就这么简单。

请注意,UIView.animate(...) 是一个 方法。这意味着该类以某种方式参与了生命周期管理。

模仿它的一个直接选项是稍微更改您的界面,这样您就可以让类为您完成,而不是直接创建 MyXMLParser:

class MyXMLParser : NSObject, XMLParserDelegate {

private static var createdParsers: Set<MyXMLParser> = []

static func parse(_ xml: String, _ completion: @escaping (String?) -> Void) {
let newParser = MyXMLParser(xml, completion)
self.createdParsers.insert(newParser)
}

private static func parserDidEndParsing(_ parser: MyXMLParser) {
self.createdParsers.remove(parser)
}

private let parser: XMLParser
private let completion: (String?) -> Void

private init(_ xml: String, _ completion: @escaping (String?) -> Void) {
// Same as existing code
}

//...

func parserDidEndDocument(_ parser: XMLParser) {
//...
MyXMLParser.parserDidEndParsing(self)
}
}

这里,一个单独的解析器由其类拥有,您可以通过调用 MyXMLParser.parse(myXmlString) { (text) in/* whatever */} 创建一个解析器。重要的是要注意 parserDidEndDocument 中的清理步骤,从类的存储集合中删除实例,这样您就不会留下未使用的实例。

关于ios - 允许完成处理程序在创建它的本地范围内存活,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54755755/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com