我有一个实例化的swift对象和一个不使用ARC的Objective C类。它是从init实例化的,并在dealloc方法中将其释放(它存储在@property中,因此我将release发送到它的后备变量中)。但是,在内存图中,我看到无论何时实例化此对象(每当用户访问应用程序中的屏幕时都会使用该对象),它永远不会被释放。它只是在内存图中显示为一个孤立的对象。我看到它内部在一个封闭中创建了一个保留周期,但是我使它变弱了,但问题仍然存在。 关于如何进一步调试此问题的任何建议?
我能想到的唯一的麻烦是这种封闭,但是现在它使用了弱自我,但泄漏仍然存在:
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)
}
}
}
}
答案 0 :(得分:0)
如果图形显示的对象没有任何强引用(即没有指向它的箭头),则问题可能不在于此Swift代码,而是Objective-C代码中的手动引用计数。
您可以采取一些措施来诊断此问题:
使用静态分析器( shift + 命令 + B 或“产品”»“分析”),这令人惊讶擅长分析Objective-C手册中的内存使用模式,保留计数代码。
malloc堆栈功能通常会很有帮助(命令 + << / kbd>或“产品”»“方案”»“编辑方案...”,然后转到“运行”»“诊断”,然后检查“ Malloc堆栈”)。如果执行此操作,则调试图还将准确显示对象的实例化位置(以防在对象实例化的位置上造成混淆。)
Instruments中的“分配”工具可以向您显示对象的完整malloc /保留/释放历史记录。因此启动仪器(命令 + i 或“产品资料”),选择“泄漏”仪器(也带“分配”工具),开始记录,锻炼应用程序,停止记录,现在您可以分析与此对象有关的分配。例如,如果将该对象称为Foo
,则可以在屏幕底部的搜索栏中搜索该对象。找到Foo
分配后,可以点击旁边的小箭头:
这将为您显示该类型的分配列表,您可以再次单击内存地址旁边的小箭头以查看详细信息:
这将向您显示所有分配,保留和释放。由此,您可以诊断出附加的retain
在哪里或丢失的release
在哪里。
在我的示例中,可以看到我在viewDidLoad
中创建了它,Foo
做了自己的平衡retain
和release
,但是没有最终的{ release
中的{1}}。您的情况可能会有所不同,但这显示了您如何诊断正在发生的事情。