但是今天我在事件处理代码中遇到了大量的内存泄漏。我追踪了问题并将其减少到以下最简示例。
假设有一个定义了单个属性“value”的协议Item:
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
}
}
如果使用内存泄漏配置在Instruments中进行分析,每当创建一个带有FooItem
的ItemWrapper
值时,就会出现内存泄漏。
let item = FooItem(value: "protocol value", additionalValue: "foo item value")
let _ = ItemWrapper(item: item)
这里有一个示例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项目。