【问题标题】:Swift memory management hole: boundary case, feature or bug?Swift 内存管理漏洞:边界情况、特性还是错误?
【发布时间】:2014-09-29 11:35:20
【问题描述】:

也许这会为某人节省一个或几个小时的调试时间。在 Swift 中实现 XML 解析器,类似于 Objective-C,看起来很简单:

private class Customparser : NSObject,NSXMLParser
{
    // ... implement the parser protocol methods
}

...

let parser=NSXMLParser(data:data)
parser.delegate=CustomParser()
let success=parser.parse()

此代码因运行时错误(访问不正确)而失败。

【问题讨论】:

    标签: xml parsing memory swift


    【解决方案1】:

    事实证明,主要问题是分配给 parser.delegate 属性会立即触发自动引用计数释放,因为它是一个“分配”属性。因此,如果读取器连接到不同的对象实例,它的寿命足以实际执行其任务:

    let reader=CustomParser()
    let parser=NSXMLParser(data:data)
    parser.delegate=reader
    let success=parser.parse()
    

    事后看来,很难说这是否是一个错误,因为它与底层 Objective-C 框架的行为方式是一致的,但对于刚开始使用 Swift 的人来说,这肯定是这样的。

    还有另一个问题:将解析器类声明为私有不会导致任何编译器错误,但它会导致运行时崩溃。取出私人修饰符解决了这个问题。这是否意味着私有类的编译方式意味着它们不能移交给其他代码块?

    【讨论】:

    • 我会打开有关崩溃的雷达 (bugreport.apple.com)。编译器应该能够检测到parser.delegate=CustomParser() 无效(因为CustomParser 符合所需协议的事实是私有的,因此NSXMLParser 不应该看到)。在编译器中修复它可能很困难,但要求它是合理的。至于内存管理,这是您的错误(您永远不会持有强引用),但期望静态分析器检测到这种错误可能是合理的。雷达可能是合理的。
    猜你喜欢
    • 1970-01-01
    • 2012-08-16
    • 2011-10-29
    • 2012-07-12
    • 2023-01-24
    • 1970-01-01
    • 1970-01-01
    • 2011-11-15
    • 1970-01-01
    相关资源
    最近更新 更多