【发布时间】:2017-07-24 22:42:23
【问题描述】:
我在 Swift 中发现了内存泄漏。它让我做噩梦,因为我的代码到处都是小漏洞,然后我设法将其简化为这个小例子,
import UIKit
enum LeakingEnum {
case
LeakCase,
AnotherLeakCase
}
class Primitive {
var lightingType: LeakingEnum = .LeakCase
var mysub : [Int] = []
init() {
mysub.append(80)
}
}
class ViewController: UIViewController {
var prim: Primitive?
override func viewDidLoad() {
super.viewDidLoad()
prim = Primitive()
}
}
如果您在 iPhone 上运行此程序并使用 Instruments 进行配置文件,您会在 Array._copyToNewBuffer 中发现此泄漏,
如果我删除对mysub.append 的调用,它将停止泄漏。如果我从Primitive 中删除枚举,它也会停止泄漏。我有这样的枚举泄漏的所有类。 Swift 枚举发生了什么?
在 iPhone6 和 iPad Pro 上的 Swift 3、Xcode 8.2.1 和 iOS 10.2 中重现。无法在模拟器或装有 iOS 9.3.2 的设备中重现。 你可以在这里下载一个最小的示例应用程序:https://github.com/endavid/SwiftLeaks
这是一个已知的错误吗?有什么解决办法吗?
编辑:
因为这让我想起了另一个枚举错误Accessor gives the wrong value in Swift 1.2/2.0 Release build only,所以我尝试将枚举设为@objc Int 枚举,但它仍然泄漏。但是,将lightingType 直接设为Int 确实可以修复泄漏...
编辑2: 将我的 iPhone 更新到 10.3 并将 Xcode 更新到 8.3 后,泄漏就消失了。好像是 iOS 10.2 的问题……
【问题讨论】:
-
由于您在将其提炼成一个小示例方面做得非常出色,因此最好的方法是在 bugs.swift.org 上打开一个缺陷。
-
令人费解。根据定义,泄漏是在对象不再使用后仍然存在的内存分配。我将 var Prim 移动到 viewDidLoad 函数中,并引用它以确保编译器没有删除它。没有泄漏!也许是仪器问题?
-
这是一个 Swift 问题,还是与实现有关的问题?我没有 Linux 可以尝试其他实现...所以我向 Apple 报告了它(错误号 30856358)
-
我创建了与 Cocoa (Mac) 应用程序相同的测试用例。它不会泄漏。此外,您的测试用例不会在模拟器下报告泄漏。所以绝对是苹果的问题。
-
感谢您的检查。苹果回复说他们无法重现这个问题......我也试过模拟器,它没有泄漏......它确实在我的 10.2 的 iPhone 6 上泄漏,我今天更新到 10.2.1,它仍然泄漏.
标签: ios swift memory-leaks enums