15

我正在 Swift 2(Xcode 7 beta 3)中开发一个应用程序,并且我正在尝试尽可能使用值类型(结构和枚举)。根据 Apple 关于内存管理的文档,使用值类型不应导致任何保留周期,它应该可以正常工作。

但是今天我在事件处理代码中遇到了大量的内存泄漏。我对其进行了跟踪并将问题简化为以下最小示例。

假设有一个协议Item定义了一个属性value

protocol Item {

    var value: String { get }

}

然后我们创建一个具体的结构来实现Item协议并添加一个额外的属性additionalValue。让我们调用 struct FooItem

struct FooItem<T>: Item {

    let value: String
    let additionalValue: T

    init(value: String, additionalValue: T) {
        self.value = value
        self.additionalValue = additionalValue
    }

}

难题的第三部分是另一个结构,它包装了实现Item协议的项目。它被称为ItemWrapper

struct ItemWrapper {

    let item: Item

    init(item: Item) {
        self.item = item
    }

}

如果使用 Memory Leaks 配置在 Instruments 中进行分析,则每次ItemWrapper使用FooItem.

let item = FooItem(value: "protocol value", additionalValue: "foo item value")  
let _ = ItemWrapper(item: item) 

仪器截图1 仪器截图2

这是示例Xcode 项目Instruments 文件https ://www.dropbox.com/s/z6ugxzxqggrv1xl/SwiftStructsMemoryLeak.zip?dl=0

整个代码示例可以在这个 Gist 中查看:https ://gist.github.com/lukaskubanek/4e3f7657864103d79e3a

这是错误报告:rdar://21375421

它是 Swift 编译器中的错误还是我做错了什么?


编辑 1:正如评论中所建议的,我在Apple Dev Forum上重新发布了这个问题,以吸引 Swift 社区以及可能来自该语言开发人员的更多关注。由于 WWDC 2015 期间开发论坛的迁移,我不得不在新论坛上发布更新的问题。这是链接:https ://forums.developer.apple.com/message/9643


编辑 2:我最初在示例代码中发布的问题似乎在Swift 2.0中得到解决。由于它没有解决我的应用程序中的问题,我对示例代码进行了另一次修改。现在FooItem' 的附加属性具有泛型类型并FooItem使用类型注释,因此是泛型类型。这就是我在我的应用程序中使用它的方式,它仍然会导致内存泄漏,但这次ItemWrapper是在初始化时而不是在访问属性时。


编辑 3:将问题完全更新为在 Swift 2.0 中仍然存在的修改问题,并上传了新的示例 Xcode 项目。

4

2 回答 2

4

尽管我在开发论坛和错误跟踪器中都没有得到 Apple 的回复,而且我在最新 beta 版本的发行说明中也没有找到与此问题相关的任何内容,但它似乎在 Swift 编译器中得到了解决在Xcode 7 beta 5中。(也许它也适用于 beta 4。我检查的最后一个版本是 beta 3。)

演示项目不再产生内存泄漏。我的应用程序也是如此。耶!

在此处输入图像描述

于 2015-08-11T08:08:22.673 回答
3

好吧,这是一个解决方法,尽管我不知道它为什么会起作用。我注意到如果你这样做:

    let theItem = itemWrapper.item
    let value = theItem.value

...而不是这个:

    let value = itemWrapper.item.value

...它不会产生内存泄漏。

于 2015-06-04T21:51:38.000 回答