Swift结构中的内存泄漏 - 如何解决这个问题?

时间:2015-06-03 19:05:30

标签: ios macos memory-leaks swift2 xcode7

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

但是今天我在事件处理代码中遇到了大量的内存泄漏。我将其追踪并将问题减少到以下最小的例子。

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

protocol Item {

    var value: String { get }

}

然后,我们创建一个实现Item协议的具体结构,并添加一个额外的属性additionalValue。让我们调用结构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) 

Instruments screenshot 1 Instruments screenshot 2

以下是示例 Xcode项目工具文件https://www.dropbox.com/s/z6ugxzxqggrv1xl/SwiftStructsMemoryLeak.zip?dl=0

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

以下是错误报告: rdar:// 21375421

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

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

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

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

2 个答案:

答案 0 :(得分:4)

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

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

enter image description here

答案 1 :(得分:3)

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

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

......而不是:

    let value = itemWrapper.item.value

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