简体   繁体   English

ObjC 中使用的 swift 对象的内存泄漏

[英]Memory leak with swift object used from ObjC

I have a swift object that is instantiated from and Objective C class that does not use ARC.我有一个从不使用 ARC 的 Objective C 类实例化的 swift 对象。 It is instantiated from the init and in the dealloc method is release it (it's stored in a @property so I send release to it's backing variable).它从 init 实例化,并在 dealloc 方法中释放它(它存储在 @property 中,因此我将释放发送到它的后备变量)。 However in the memory graph I see that whenever I instantiate this object (it's used whenever a users accesses a screen in the app) it never gets released.然而,在内存图中,我看到每当我实例化这个对象(每当用户访问应用程序中的屏幕时使用它)它永远不会被释放。 It just appears as a lone object in the memory graph.它只是在内存图中显示为一个单独的对象。 I saw that inside it it was creating a retain cycle in a closure but I made it weak there yet the problem persists.我看到它在内部创建了一个闭包中的保留循环,但我在那里使它变弱,但问题仍然存在。 Any suggestions on how to further debug this issue?有关如何进一步调试此问题的任何建议?

The only coulprit I could think of was this closure, but it uses weak self now, yet the leak persists:我能想到的唯一罪魁祸首是这个闭包,但它现在使用弱 self ,但泄漏仍然存在:

var observerToken : NSObjectProtocol?

@objc public override init() {
    self.accessToken = ""

    super.init()
    RPScreenRecorder.shared().delegate = self

    if #available(iOS 12.0, *) {
        self.observerToken = NotificationCenter.default.addObserver(forName: UIScreen.capturedDidChangeNotification, object: UIScreen.main, queue: OperationQueue.main) { [weak self] (notification)  in

            guard let strongSelf = self else { return }
            if strongSelf.broadcastPickerView != nil && strongSelf.screenTrack == nil {
                let isCaptured = UIScreen.main.isCaptured

                strongSelf.updateScreenSharingIcon(screenIsShared: isCaptured)
            }
        }
    }
}

If the graph is showing this object without any strong references (ie no arrow pointing to it), the problem is probably not this Swift code, but rather the manual reference counting in the Objective-C code.如果图表显示这个对象没有任何强引用(即没有箭头指向它),问题可能不是这个 Swift 代码,而是 Objective-C 代码中的手动引用计数。

There are a few things you can do to diagnose this:您可以做一些事情来诊断这个问题:

  1. Use the static analyzer ( shift + command + B or “Product” » “Analyze”), which is surprisingly good at analyzing the memory use patterns in Objective-C manual retain counting code.使用静态分析器( shift + command + B或 “Product” » “Analyze”),它在分析 Objective-C 手册中保留计数代码中的内存使用模式方面出奇的好。

  2. Often the malloc stack feature can be helpful ( command + < or “Product” » “Scheme” » “Edit Scheme...” and then go to “Run” » “Diagnostics” and check “Malloc Stack”).通常 malloc 堆栈功能会很有帮助(命令+ <或“产品”»“方案”»“编辑方案...”然后转到“运行”»“诊断”并检查“Malloc 堆栈”)。 If you do this, then the debug graph will also show you precisely where the object was instantiated (in case there might be some confusion about where the object was instantiated.)如果您这样做,那么调试图还将准确地显示对象的实例化位置(以防可能对对象的实例化位置有些混淆。)

  3. The “Allocations” tool in Instruments can show you the full malloc/retain/release history of the object. Instruments 中的“分配”工具可以显示对象的完整 malloc/retain/release 历史。 So fire up Instruments ( command + i or “Product Profile”), choose the “Leaks” instrument (which brings in the “Allocations” tool, too), start recording, exercise the app, stop recording, and now you can analyze the allocations related to this object.因此,启动 Instruments( command + i或“Product Profile”),选择“Leaks”工具(它也会引入“Allocations”工具),开始记录,运行应用程序,停止记录,现在您可以分析与此对象相关的分配。 For example, if the Object was called Foo , you'd search for that in the search bar at the bottom of the screen.例如,如果对象名为Foo ,您将在屏幕底部的搜索栏中搜索该对象。 When you find Foo allocations, you can tap the little arrow next to it:当您找到Foo分配时,您可以点击它旁边的小箭头:

    在此处输入图片说明

    That will show you the list of allocations for that type, and you can again click on the little arrow next to the memory address to see the details:这将显示该类型的分配列表,您可以再次单击内存地址旁边的小箭头以查看详细信息:

    在此处输入图片说明

    That shows you every allocation, retain, and release.这会向您显示每个分配、保留和释放。 From that, you can diagnose where the additional retain or where the missing release is.从中,您可以诊断额外的retain或丢失的release在哪里。

    In my example, I can see that I created it in viewDidLoad , that Foo did its own balanced retain and release , but that there is no final release in dealloc .在我的示例中,我可以看到我在viewDidLoad创建了它, Foo做了它自己的平衡retainrelease ,但在dealloc没有最终release Your scenario will likely be different, but this shows how you can diagnose what's going on.您的情况可能会有所不同,但这显示了您如何诊断正在发生的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM