我正在Swift 2(Xcode 7 beta 3)中开发一个应用程序,我尝试在可能的情况下使用值类型(struct和enums)。根据苹果关于内存管理的文档,使用值类型应该不会导致任何保留循环,它应该只是工作。
但是今天我在事件处理代码中遇到了大量的内存泄漏。我跟踪了它,并将问题简化为以下最小的示例。
假设有一个协议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
}
}
第三部分是另一个结构体,它 Package 了一个实现Item
协议的项,称为ItemWrapper
。
struct ItemWrapper {
let item: Item
init(item: Item) {
self.item = item
}
}
如果在“仪器”中使用“内存泄漏”配置进行评测,则每次使用FooItem
创建ItemWrapper
值时都会出现内存泄漏。
let item = FooItem(value: "protocol value", additionalValue: "foo item value")
let _ = ItemWrapper(item: item)
x1c 0d1x
以下是示例Xcode项目和乐器文件:https://www.dropbox.com/s/z6ugxzxqggrv1xl/SwiftStructsMemoryLeak.zip?dl=0
整个代码示例可在此Gist中查看:https://gist.github.com/lukaskubanek/4e3f7657864103d79e3a
下面是错误报告:读取日期://21375421
是Swift编译器中的bug还是我做错了什么?
EDIT 1:正如评论中所建议的,我在Apple Dev Forum上重新发布了这个问题,以吸引Swift社区以及潜在的该语言开发者的更多关注。由于2015年WWDC期间开发论坛的迁移,我不得不在新论坛上发布一个更新的问题。以下是链接:https://forums.developer.apple.com/message/9643
编辑2:我最初在示例代码中发布的问题似乎在Swift 2.0中得到了解决。由于它没有解决我的应用程序中的问题,我对示例代码进行了另一次修改。现在FooItem
的附加属性有一个泛型类型,并且FooItem
用该类型进行了注解,因此是一个泛型类型。这就是我如何'我在我的应用程序中使用它,它仍然会导致内存泄漏,但这一次是在初始化ItemWrapper
时,而不是在访问属性时。
EDIT 3:将问题完全更新为Swift 2.0中存在的已修改问题,并上传新的示例Xcode项目。
2条答案
按热度按时间hxzsmxv21#
虽然我在开发论坛和bug追踪器上都没有得到苹果的回应,我也没有在最新测试版的发行说明中找到任何与这个问题相关的东西,但这个问题似乎在Xcode 7 beta 5中的Swift编译器中得到了解决。(也许它在beta 4中也能工作。我检查的最后一个版本是beta 3。)
演示项目不再产生内存泄漏。我的应用程序也是如此。耶!
bq9c1y662#
这里有一个解决方法,虽然我不知道为什么它会起作用。我注意到如果你这样做:
...而不是这样:
...它不会产生内存泄漏。