未持有引用导致泄漏,弱引用无法解决问题

3
我遇到了一些内存管理问题。我有一个UIViewController的子类,我手动设置它的视图,以便有一个回指向viewController并避免引用循环,我使用了weak/unowned。现在的问题是,如果我使用unowned,那么我会有一个内存泄漏,但如果我使用weak,则不会有一个。我搞不清楚为什么会这样发生?
更新: 好像是个bug。
控制台输出:
removing vc
view Controller deinitialized
custom view deinitialized

我正在使用Xcode 8.3.1

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    window = UIWindow(frame: UIScreen.main.bounds)
    window?.rootViewController = ViewController(nibName: nil, bundle: nil)
    window?.makeKeyAndVisible()

    DispatchQueue.main.asyncAfter(deadline: .now() + 5) { 
        print("removing vc")
        self.window?.rootViewController = nil
    }

    return true
}


class ViewController: UIViewController {

    override func loadView() {
        view = CustomView(frame: .zero, vc: self)
        view.backgroundColor = .red
    }

    deinit {
        print("view Controller deinitialized")
    }
}

class CustomView:UIView{

    init(frame: CGRect , vc:ViewController) {
        self.vc = vc
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    //    weak var vc : ViewController!   // no leak
    unowned var vc : ViewController   // leak

    deinit {
        print("custom view deinitialized")
    }
}

1
你是如何确定存在内存泄漏的?也许你的方法有误,或者这可能是(不太可能的)编译器错误。 - Alistra
这两个工具和内存图表都显示出来,这是一个内存泄漏。 - user7649191
2
请@Alan尝试重写deinit并在其中打印一些信息,以此检查,因为Swift的工具可能尚未正常工作。我个人遇到了假阳性。也许你的泄漏甚至不是泄漏。 - Alistra
1
你使用Xcode 8.1.3吗?泄漏工具出现了官方问题。建议尝试使用Xcode 8.2再次检查! - ObjectAlchemist
这可能对你没有任何帮助,但通常来说,如果你遵循MVC模式,你的视图不应该像这样链接回你的视图控制器。例如,创建一个代理协议来支持这种通信。 - Paulo Mattos
显示剩余5条评论
1个回答

3

Xcode 8.2版本说明:

针对macOS和iOS Simulator的内存调试器已经修复了一个问题,即在包含枚举类型字段或继承自某些Objective-C框架类的Swift类中报告错误的内存泄漏。 (27932061)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接