草庐IT

ios - 弹出 UIViewController 后,MKMapView autorelease 不调用 dealloc

coder 2023-09-24 原文

我在 A 类中有以下代码:

UIViewController *vc = [self viewControllerForItem:item];

我的应用程序委托(delegate)中的 viewControllerForItem 方法返回基于我的项目的 UIViewController,即

vc = [[[MyCustomViewController alloc] init] autorelease];

return vc;

然后我推送 View Controller :

[self.navigationController pushViewController:vc animated:YES];

我试图推送的这个 VC 是一个 MKMapView,我在 dealloc 方法中插入了一条日志语句,以查看它是否被调用。在我的内存使用中,增长速度非常快。

但是,当我在推送VC后添加如下代码时:

[vc release];

我的 MKMapView 类调用 dealloc 方法。

当然,如果 MKMapView 类是我的应用程序委托(delegate)返回的唯一类(或者我可以只检查 VC 的类是否是我的 MKMapView 类),这将是一个简单的解决方案。但是,我想解决这个问题的根源。

  1. 如果我在 View Controller 上设置了自动释放,为什么没有调用 dealloc?

  2. 即使在该 vc 上使用了自动释放,我怎么可能将 [vc release] 添加到 View Controller ?

谢谢

编辑:

这里有一些额外的信息。我的应用程序委托(delegate)中有 viewControllerForItem 类。我将自动释放的对象返回到我的另一个管理器类中,然后在其中推送 View Controller 。当我返回一个自动释放的对象,然后将其推送到其他类时,保留计数是否被弄乱了?

这是我推送 VC 和调用 mkmapview 的 didDissappear 时的回溯/调用堆栈:

pushVC: (
0   NewHampshire                        0x00254cdf -[CustomViewController navigateToRowId:withLinkBehavior:animated:] + 2111
1   NewHampshire                        0x002534c9 -[CustomViewController webView:shouldStartLoadWithRequest:navigationType:] + 841
2   UIKit                               0x02caf288 -[UIWebView webView:decidePolicyForNavigationAction:request:frame:decisionListener:] + 318
3   UIKit                               0x02cb1854 -[UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:] + 77
4   CoreFoundation                      0x05d0bd1d __invoking___ + 29
5   CoreFoundation                      0x05d0bc2a -[NSInvocation invoke] + 362
6   CoreFoundation                      0x05d0bdaa -[NSInvocation invokeWithTarget:] +     74
7   WebKit                              0x0a4d811d -[_WebSafeForwarder forwardInvocation:] + 157
8   CoreFoundation                      0x05d076da ___forwarding___ + 458
9   CoreFoundation                      0x05d074ee _CF_forwarding_prep_0 + 14
10  CoreFoundation                      0x05d0bd1d __invoking___ + 29
11  CoreFoundation                      0x05d0bc2a -[NSInvocation invoke] + 362
12  WebCore                             0x09533b29 _ZL20HandleDelegateSourcePv + 121
13  CoreFoundation                      0x05ca083f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
14  CoreFoundation                      0x05ca01cb __CFRunLoopDoSources0 + 235
15  CoreFoundation                      0x05cbd29e __CFRunLoopRun + 910
16  CoreFoundation                      0x05cbcac3 CFRunLoopRunSpecific + 467
17  CoreFoundation                      0x05cbc8db CFRunLoopRunInMode + 123
18  GraphicsServices                    0x059749e2 GSEventRunModal + 192
19  GraphicsServices                    0x05974809 GSEventRun + 104
20  UIKit                               0x02a6ed3b UIApplicationMain + 1225
21  NewHampshire                        0x000150dd main + 125
22  libdyld.dylib                       0x04fab70d start + 1
)

disappear: (
0   NewHampshire                        0x0014631d -[CustomAdvancedGPSMapViewController viewDidDisappear:] + 173
1   UIKit                               0x02b85bac -[UIViewController _setViewAppearState:isAnimating:] + 341
2   UIKit                               0x02b86328 -[UIViewController __viewDidDisappear:] + 150
3   UIKit                               0x02b86461 -[UIViewController _endAppearanceTransition:] + 306
4   UIKit                               0x02ba549a -[UINavigationController navigationTransitionView:didEndTransition:fromView:toView:] + 738
5   UIKit                               0x02b9d403 __49-[UINavigationController _startCustomTransition:]_block_invoke + 206
6   UIKit                               0x03176740 -[_UIViewControllerTransitionContext completeTransition:] + 99
7   UIKit                               0x02a63454 __53-[_UINavigationParallaxTransition animateTransition:]_block_invoke105 + 680
8   UIKit                               0x02ad1005 -[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] + 306
9   UIKit                               0x02abac6c -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 267
10  UIKit                               0x02abaf58 -[UIViewAnimationState animationDidStop:finished:] + 80
11  QuartzCore                          0x028b2a44 _ZN2CA5Layer23run_animation_callbacksEPv + 304
12  libdispatch.dylib                   0x04d194b0 _dispatch_client_callout + 14
13  libdispatch.dylib                   0x04d0775e _dispatch_main_queue_callback_4CF + 340
14  CoreFoundation                      0x05d7ca5e __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 14
15  CoreFoundation                      0x05cbd6bb __CFRunLoopRun + 1963
16  CoreFoundation                      0x05cbcac3 CFRunLoopRunSpecific + 467
17  CoreFoundation                      0x05cbc8db CFRunLoopRunInMode + 123
18  GraphicsServices                    0x059749e2 GSEventRunModal + 192
19  GraphicsServices                    0x05974809 GSEventRun + 104
20  UIKit                               0x02a6ed3b UIApplicationMain + 1225
21  NewHampshire                        0x0001507d main + 125
22  libdyld.dylib                       0x04fab70d start + 1
)

解决方案:虽然这篇文章中的回复没有提供我的问题的确切解决方案,但 Darren 使用 instruments 工具无疑将我引导到了正确的方向。我发现罪魁祸首是未正确释放的 CABasicAnimation 对象。

在 viewWillDisappear 方法中,我为 CABasicAnimation 对象添加了以下内容:

self.rotationAnimation.delegate = nil;
self.rotationAnimation = nil; 

最佳答案

使用 Instruments 跟踪 CustomAdvancedGPSMapViewController 和/或 MKMapView 的保留/释放历史:

  • 在 Xcode 中,从菜单中选择“产品 > 配置文件”。

  • Instruments 启动时,选择“Allocations”模板。

  • 如果您的应用自动启动,请单击“停止”按钮将其停止。

  • 点击 Allocations 工具上的“i”按钮,然后选中“Record reference counts”。

  • 从菜单中选择“查看 > 扩展详细信息”。

  • 点击“录制”按钮启动您的应用,并等待您的应用在模拟器中启动。

  • 在模拟器中,使用您的应用导航到 CustomAdvancedGPSMapViewController。

  • 在 Instruments 中,点击“暂停”按钮

  • 使用窗口右上角的搜索字段并搜索 CustomAdvancedGPSMapViewController。 CustomAdvancedGPSMapViewController 应该出现在分配摘要列表中。

  • 在分配摘要列表中,单击 CustomAdvancedGPSMapViewController 名称旁边的 -> 箭头。这应该表明您的应用程序中有一个事件的 CustomAdvancedGPSMapViewController 实例。

  • 点击地址旁边的 -> 箭头。这将显示此 CustomAdvancedGPSMapViewController 实例的保留/释放历史记录。

  • 取消暂停 Instruments,返回到模拟器,关闭您的 CustomAdvancedGPSMapViewController 并返回到您认为应该解除分配 Controller 的位置。

  • 返回 Instruments,再次点击“暂停”,查看更新后的保留/发布历史。

保留/释放历史中的第一个事件应该是“malloc”。选择此行,窗口右侧的“扩展详细信息” View 将显示此分配的堆栈跟踪。您应该在堆栈跟踪中看到您自己的代码。双击堆栈跟踪中的代码,您应该会看到分配了 CustomAdvancedGPSMapViewController 实例的代码行。

在代码 View 上方,单击“历史”选项卡返回到历史列表。

保留/释放历史中的最后一个事件应该是“免费的”。如果不是这种情况,则可能存在泄漏。检查保留/释放历史并查找不匹配的保留。可能有很多噪音,与 CoreAnimation 等相关。查找您的代码出现在堆栈跟踪中的事件。

将保留/释放历史与未泄漏的不同 View Controller 进行比较。

如果 CustomAdvancedGPSMapViewController 没有泄漏,请尝试检查 MKMapView 的历史记录。

关于ios - 弹出 UIViewController 后,MKMapView autorelease 不调用 dealloc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21124425/

有关ios - 弹出 UIViewController 后,MKMapView autorelease 不调用 dealloc的更多相关文章

  1. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  2. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  3. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  4. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  5. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  6. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  7. ruby - 调用其他方法的 TDD 方法的正确方法 - 2

    我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent

  8. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  9. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  10. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

随机推荐