我在A类中有以下代码:
UIViewController *vc = [self viewControllerForItem:item];
其中我的app委托中的viewControllerForItem方法返回基于我的项目的UIViewController,即
vc = [[[MyCustomViewController alloc] init] autorelease];
return vc;
然后我按下视图控制器:
[self.navigationController pushViewController:vc animated:YES];
我试图推送的这个VC是一个MKMapView,我在dealloc方法中插入了一个日志语句,看它是否被调用。在我的记忆中,增长速度非常快。
但是,当我按下VC后添加以下代码时:
[vc release];
我的MKMapView类调用dealloc方法。
当然,如果MKMapView类是我的app委托返回的唯一类(或者我可以检查VC的类是否是我的MKMapView类),这将是一个简单的解决方案。但是,我想解决这个根本问题。
如果我在视图控制器上设置autorelease,为什么不调用dealloc?
即使在该vc上使用autorelease,我怎么可能将[vc release]添加到视图控制器?
由于
编辑:
这是一些额外的信息。我的app委托中有viewControllerForItem类。我将自动释放的对象返回到我的其他管理器类中,然后我按下视图控制器。当我返回一个自动释放的对象时,保留计数是否被搞砸了,然后将其推送到其他类中?
当我推送VC并调用mkmapview的didDissappear时,这是backtrace / callstack:
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对象。
在viewWillDisappear方法中,我为CABasicAnimation对象添加了以下内容:
self.rotationAnimation.delegate = nil;
self.rotationAnimation = nil;
答案 0 :(得分:8)
使用工具跟踪CustomAdvancedGPSMapViewController
和/或MKMapView
的保留/发布历史记录:
在Xcode中,从菜单中选择“产品>配置文件”。
当仪器启动时,选择“分配”模板。
如果您的应用自动启动,请点击“停止”按钮停止它。
单击分配工具上的“i”按钮,然后选中“记录参考计数”。
从菜单中选择“查看>扩展详细信息”。
点击“录制”按钮启动您的应用,等待您的应用在模拟器中启动。
在模拟器中,使用您的应用导航到CustomAdvancedGPSMapViewController。
在仪器中,单击“暂停”按钮
使用窗口右上角的搜索字段搜索CustomAdvancedGPSMapViewController。 CustomAdvancedGPSMapViewController应出现在“分配摘要”列表中。
在“分配摘要”列表中,点击 - > CustomAdvancedGPSMapViewController名称旁边的箭头。这应该表明您的应用程序中有一个CustomAdvancedGPSMapViewController实例。
点击 - >地址旁边的箭头。这将显示此CustomAdvancedGPSMapViewController实例的保留/发布历史记录。
取消暂停仪器,返回模拟器,关闭CustomAdvancedGPSMapViewController并返回到您认为应该取消分配控制器的位置。
返回“工具”,再次单击“暂停”,查看更新的保留/发布历史记录。
保留/释放历史记录中的第一个事件应为“malloc”。选择此行,窗口右侧的“扩展详细信息”视图将显示此分配的堆栈跟踪。您应该在堆栈跟踪中看到自己的代码。双击堆栈跟踪中的代码,您应该看到分配了CustomAdvancedGPSMapViewController实例的代码行。
在代码视图上方,单击“历史记录”选项卡返回历史记录列表。
保留/发布历史记录中的最后一个事件应该是“免费”的。如果不是这种情况可能会发生泄漏。检查保留/释放历史记录并查找无与伦比的保留。可能存在很多与CoreAnimation相关的噪声等。查找代码出现在堆栈跟踪中的事件。
将保留/释放历史记录与未泄漏的其他视图控制器进行比较。
如果CustomAdvancedGPSMapViewController
没有泄露,请尝试检查MKMapView
的历史记录。
答案 1 :(得分:2)
您编写的代码是正确的,您不应该发布vc,因为它已经自动释放了。
-(UIViewController *) viewControllerForItem: (Item*)item
{
/* create controller for the item --
* alloc init with increase the retain count of your object by 1
* autorelease will reduce the retain count of the object by 1
*/
return [[[MyCustomViewController alloc] init] autorelease];
}
UIViewController *vc = [self viewControllerForItem:item];
[self.NavigationController pushViewController:vc];
你不能释放'vc',因为你没有拥有它,因为你没有为它做“alloc init”或“retain”。
我遇到了Mapview即使在发布后也没有释放内存的问题。它似乎是一个苹果bug,只有当你获得mapview的内存警告时,这个内存才会被销毁。但你可以通过破解来强制释放。
更改mapType似乎释放了mapview所持有的内存。因此,请尝试在mapviewcontroller中发布mapview对象之前重置mapType。您可以在执行该语句后看到内存中断。
- (void)dealloc
{
// this is a trick for releasing memory
__mapView.mapType = MKMapTypeStandard;
[__mapView removeFromSuperview];
__mapView.delegate = nil;
[__mapview release];
[super dealloc];
}
希望它有所帮助。