自从我上次检查以来(至少)已经几个月(至少),我在我的应用程序上运行了一种工具来检查内存泄漏,并且我为我的应用程序添加了新功能并重构了一些代码。当我开始运行时,第一项检查(加载了主视图控制器,并具有6个按钮,一个标签和6个自定义UI视图,这些视图本质上只是带有一些图像的标签)看起来一切都很好,但是第二项检查让我大吃一惊,说我有1460次新泄漏。当我在应用程序中所做的全部工作是按下一个按钮以按下另一个视图控制器时,这看起来确实很高(尽管这不是一个简单的视图控制器,但是它也没有做任何花哨的事情)。
查看泄漏列表,只有7个被标记为我的应用故障,其他1453是以下系统库:
我在应用程序中执行的次数越多,出现的系统库就越多,我可以轻松实现数千次泄漏。
查看所有不同的堆栈跟踪,奇怪的是,它们中的大约一半(从我看过的所有随机跟踪中)都具有从lookUpImpOrForward
或{{1 }}功能,如下面的屏幕截图所示。
当我查看由我的应用程序引起的泄漏时,它们全部在堆栈跟踪的顶部都具有这五个功能,而我的应用程序的功能就在其下方。当我双击堆栈跟踪中的函数以查看分配泄漏内存的代码行时,我会被带到类似
的行_objc_msgSend_uncached
或
label = [[UILabel alloc] init];
第一个应该是完全安全的,因为我没有在该类中做任何花哨的内存方面的事情,而且我不知道第二个怎么可能甚至会涉及到内存泄漏,因为它不处理任何指针。
为缩小原因范围,我再次运行并按下另一个按钮,该按钮将我带到视图控制器,该控制器在加载时不执行任何操作,并且仅包含导航栏,6个按钮(4个带有图像)和3个标签-非常基本的东西。仍然,按下按钮后,我在支票上收到828个新泄漏。
进一步,我用Xcode创建了一个全新的单视图应用程序项目,并复制了第一个视图控制器。我在第一个视图控制器上放了一个按钮,对第二个视图控制器进行了展示,然后在第二个视图控制器上放置了标签。您可以在https://github.com/AdamNEvans/LeakySampleApp上找到代码。在仪器中运行此命令后,按下第二个视图控制器后,内存泄漏高达237。怎么样?!?!?
我不记得过去运行内存泄漏检测程序时会看到这么多泄漏。我确定我做错了什么,至少导致了一些此类泄漏,但事实是,如此之多而又不包含我的任何代码的事实,使我认为我在错误地创建了对象在许多不同的地方(我不确定如何处理CGPoint point = CGPointMake(bottomBar.frame.origin.x + 70,
bottomBar.frame.origin.y);
和alloc
调用),或者在系统库中引入了一个错误,并造成了严重破坏(我猜想是在许多堆栈跟踪顶部的常见五个函数中。
90%的泄漏在1K以下,因此该应用程序可以在这些泄漏下存活相当长的时间,但仍然令我感到担忧,因为这是一个实用程序,人们可能会花费数小时。
我已打开ARC,并在具有iOS 12.2的物理iPad Air 2上运行我的应用程序时正在使用Xcode 10.2.1。
有什么想法吗?
答案 0 :(得分:0)
在测试演示应用程序时,我还注意到了很多漏洞。与完全不同的系统库关联。 例如,渲染图像的ImageIO代码段。
没有什么可泄漏的(只有大约10行代码,是的,我知道CFRelease函数并且使用了它们,但这无济于事)。
我还注意到,在真实设备上运行的同一项目不会检测到泄漏,但是模拟器上的同一项目会泄漏。
甚至在将所有情况都在情节提要中实现的singleView项目中也存在泄漏。
P.S。
苹果每年都会发布新的操作系统和新的语言版本,即新的API。
天哪,这样的比赛是为了什么?结果,他们花时间在AR / Metal和其他东西上,却忘记了开发人员的基本工具,例如Xcode,其第六版的评分很低,经常出现故障……