弹出 UIViewController 后 MKMapView 自动释放不调用 dealloc [英] MKMapView autorelease not calling dealloc after UIViewController is popped

查看:15
本文介绍了弹出 UIViewController 后 MKMapView 自动释放不调用 dealloc的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 A 类中有以下代码:

I have the following code in class A:

UIViewController *vc = [self viewControllerForItem:item];

我的应用程序委托中的 viewControllerForItem 方法根据我的项目返回 UIViewController,即

where the viewControllerForItem method in my app delegate returns a UIViewController based on my item i.e.

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

return vc;

然后我推送视图控制器:

I then push the view controller:

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

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

This VC i'm trying to push is a MKMapView and I inserted a log statement in the dealloc method to see if it's being called. In my memory usage, the growth is increasing pretty rapidly.

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

However, when I add the following code after pushing the VC:

[vc release];

我的 MKMapView 类调用 dealloc 方法.

my MKMapView class calls the dealloc method.

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

Of course this would be a simple solution if the MKMapView class was the only class returned by my app delegate (or I could just check if the VC's class is my MKMapView class). However, I would like to solve the root problem of this.

  1. 如果我在视图控制器上设置了 autorelease,为什么不调用 dealloc?

  1. Why is the dealloc not being called if I set autorelease on my view controller?

即使在该 vc 上使用了 autorelease,我怎么可能将 [vc release] 添加到视图控制器?

How is it possible that I can add [vc release] to the view controller even though autorelease is used on that vc?

谢谢

这里有一些附加信息.我的应用程序委托中有 viewControllerForItem 类.我将自动释放的对象返回到我的另一个管理器类中,然后在其中推送视图控制器.当我返回一个自动释放的对象,然后将它推送到其他某个类时,保留计数是否被搞砸了?

Here's some additional info. I have the viewControllerForItem class in my app delegate. I'm returning the auto released object into my other manager class where I then push the view controller. Is the retain count being messed up when I return an autoreleased object, and then push it in some other class?

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

This is the backtrace / callstack right when I push the VC and when the mkmapview's didDissappear is called:

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 确实使用仪器工具将我引导到了正确的方向.我发现罪魁祸首是未正确释放的 CABasicAnimation 对象.

Solution: Although the responses in this post didn't provide the exact solution to my problem, Darren definitely steered me into the correct direction using the instruments tool. I found the culprit to be a CABasicAnimation object that was not being properly released.

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

in the viewWillDisappear method, I added the following for the CABasicAnimation object:

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

推荐答案

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

Use Instruments to track the retain/release history of CustomAdvancedGPSMapViewController and/or MKMapView :

  • 在 Xcode 中,从菜单中选择产品 > 配置文件".

  • In Xcode, select "Product > Profile" from the menu.

当 Instruments 启动时,选择Allocations"模板.

When Instruments starts, select the "Allocations" template.

如果您的应用自动启动,请点击停止"按钮将其停止.

If your app starts automatically, click the "Stop" button to stop it.

单击分配工具上的i"按钮,然后选中记录引用计数".

Click the "i" button on the Allocations instrument, and check "Record reference counts".

从菜单中选择查看 > 扩展细节".

Select "View > Extended Detail" from the menu.

点击录制"按钮启动您的应用,并等待您的应用在模拟器中启动.

Click the "Record" button to start your app, and wait for your app to start in the simulator.

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

In the simulator, use your app to navigate to the CustomAdvancedGPSMapViewController.

在乐器中,点击暂停"按钮

In Instruments, click the "Pause" button

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

Use the search field in the top-right of the window and search for CustomAdvancedGPSMapViewController. CustomAdvancedGPSMapViewController should appear in the Allocation Summary list.

在分配摘要列表中,单击 CustomAdvancedGPSMapViewController 名称旁边的 -> 箭头.这应该表明您的应用中有一个 CustomAdvancedGPSMapViewController 实例处于活动状态.

In the Allocation Summary list, Click the -> arrow next to the CustomAdvancedGPSMapViewController name. This should show that you have one instance of CustomAdvancedGPSMapViewController active in your app.

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

Click the -> arrow next to address. This will display the retain/release history for this CustomAdvancedGPSMapViewController instance.

取消暂停 Instruments,返回到模拟器,然后关闭您的 CustomAdvancedGPSMapViewController 并返回到您认为应该释放控制器的位置.

Un-pause Instruments, return to the simulator, and dismiss your CustomAdvancedGPSMapViewController and return to the point where you believe the controller should be deallocated.

返回到 Instruments,再次单击Pause",然后查看更新的保留/发布历史记录.

Return to Instruments, click "Pause" again, and look at the updated retain/release history.

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

The first event in the retain/release history should be "malloc". Select this row and the Extended Detail view in the right side of the window will display the stack trace for this allocation. You should see your own code in the stack trace. Double-click your code in the stack trace and you should see your line of code that allocated the the CustomAdvancedGPSMapViewController instance.

在代码视图上方,单击History"选项卡可返回到历史记录列表.

Above the code view, click the "History" tab to return to the history list.

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

The last event in the retain/release history should be "free". If that's not the case there may be a leak. Inspect the retain/release history and look for an unmatched retain. There may be a lot of noise, related to CoreAnimation, etc. Look for events in which your code appears in the stack trace.

将保留/释放历史记录与未泄漏的其他视图控制器进行比较.

Compare the retain/release history with a different view controller that is not leaking.

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

If CustomAdvancedGPSMapViewController isn't leaking, try inspecting the history of MKMapView.

这篇关于弹出 UIViewController 后 MKMapView 自动释放不调用 dealloc的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆