Iphone ARC-UIWebView/UIViewController是否在内存中停留?
在使用ARC时,我的旧UIWebView似乎仍然存在,出于某种原因,即使在我离开他们的UIViewController之后,它们仍然会出现在OSX Safari的开发工具中 我正在将转换分配给包含UIWebView的视图控制器,如下所示:Iphone ARC-UIWebView/UIViewController是否在内存中停留?,iphone,ios,objective-c,ios6,automatic-ref-counting,Iphone,Ios,Objective C,Ios6,Automatic Ref Counting,在使用ARC时,我的旧UIWebView似乎仍然存在,出于某种原因,即使在我离开他们的UIViewController之后,它们仍然会出现在OSX Safari的开发工具中 我正在将转换分配给包含UIWebView的视图控制器,如下所示: //Create settings view/tabbar UITabBarController *tabController = [[NoRotateTabBarController alloc] init] ; StyleView
//Create settings view/tabbar
UITabBarController *tabController = [[NoRotateTabBarController alloc] init] ;
StyleViewController *styleTab = [[StyleViewController alloc] initWithNibName:@"StyleViewController" bundle:nil];
styleTab.tabBarItem.title = @"Style";
styleTab.tabBarItem.image = [UIImage imageNamed:@"EyeIcon.png"];
NSArray *tabsArray = @[styleTab];
tabController.viewControllers = tabsArray;
prevView = self.window.rootViewController;
[UIView
transitionWithView:self.window
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^(void) {
BOOL oldState = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:NO];
self.window.rootViewController = tabController;
[UIView setAnimationsEnabled:oldState];
}
completion:nil];
[UIView
transitionWithView:self.window
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^(void) {
BOOL oldState = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:NO];
self.window.rootViewController = prevView;
[UIView setAnimationsEnabled:oldState];
}
completion:nil];
我是这样走出这个视野的:
//Create settings view/tabbar
UITabBarController *tabController = [[NoRotateTabBarController alloc] init] ;
StyleViewController *styleTab = [[StyleViewController alloc] initWithNibName:@"StyleViewController" bundle:nil];
styleTab.tabBarItem.title = @"Style";
styleTab.tabBarItem.image = [UIImage imageNamed:@"EyeIcon.png"];
NSArray *tabsArray = @[styleTab];
tabController.viewControllers = tabsArray;
prevView = self.window.rootViewController;
[UIView
transitionWithView:self.window
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^(void) {
BOOL oldState = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:NO];
self.window.rootViewController = tabController;
[UIView setAnimationsEnabled:oldState];
}
completion:nil];
[UIView
transitionWithView:self.window
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^(void) {
BOOL oldState = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:NO];
self.window.rootViewController = prevView;
[UIView setAnimationsEnabled:oldState];
}
completion:nil];
UIWebView(int StyleViewController)的创建方式如下:
@implementation StyleViewController
UIWebView *webView;
//viewDidLoad
webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 1)];
webView.scalesPageToFit = NO;
webView.scrollView.scrollEnabled = false;
webView.multipleTouchEnabled = false;
webView.alpha = 0;
webView.backgroundColor = [UIColor clearColor];
webView.opaque = false;
@end
但是,我注意到,当我在Safari中检查时,旧的UIWebView似乎正在堆积,而旧的UIWebView仍然显示在菜单中。这是Safari开发工具中的一个bug吗?是否有办法确保发布我的UIWebViews?通常,当您遇到这种情况时,您会发现某些东西正在保留这些视图。将断点或日志消息添加到所有自定义子类的dealloc方法中,并查看是否有任何自定义子类获得了dealloc。如果是这样的话,其中一个是UIWebViews的所有者,那么,您必须挖掘 如果你只是一无所获,那么就复制你的应用程序(整个文件夹),在上面的代码中去掉所有复杂的类(一个接一个),并在dealoc中使用一个简单的UIViewController子类和日志消息。使用非常简单的类,您应该能够获得项目,这样一切都可以处理。他们开始一个接一个地放回您的自定义类,直到dealloc停止。这将帮助您缩小问题的范围
Aa您可能知道,阻塞保留周期或使用强委托可能会导致问题。我确实注意到UIWebView明确指出,如果您正在使用委托,则应在处理委托之前将其设置为nil。[另外,NSURLConnection保留委托。]通常,当您遇到这种情况时,您会发现某些东西保留了视图。将断点或日志消息添加到所有自定义子类的dealloc方法中,并查看是否有任何自定义子类获得了dealloc。如果是这样的话,其中一个是UIWebViews的所有者,那么,您必须挖掘 如果你只是一无所获,那么就复制你的应用程序(整个文件夹),在上面的代码中去掉所有复杂的类(一个接一个),并在dealoc中使用一个简单的UIViewController子类和日志消息。使用非常简单的类,您应该能够获得项目,这样一切都可以处理。他们开始一个接一个地放回您的自定义类,直到dealloc停止。这将帮助您缩小问题的范围
Aa您可能知道,阻塞保留周期或使用强委托可能会导致问题。我确实注意到UIWebView明确指出,如果您正在使用委托,则应在处理委托之前将其设置为nil。[另外,NSURLConnection保留代理。]由于您在动画块中引用了
self.window.rootViewController
,因此您似乎有一个保留周期
使用ARC,将复制块,从而捕获块内使用的变量。因此,您需要创建一个对self的\u弱
引用,以便在块内使用
像这样:
__weak SomeObjectClass *weakSelf = self;
SomeBlockType someBlock = ^{
SomeObjectClass *strongSelf = weakSelf;
if (strongSelf == nil)
{
// The original self doesn't exist anymore.
// Ignore, notify or otherwise handle this case.
}
else
{
[strongSelf someMethod];
}
};
请参见“块”部分中的此处:由于在动画块中引用了
self.window.rootViewController
,因此您似乎有一个保留周期
使用ARC,将复制块,从而捕获块内使用的变量。因此,您需要创建一个对self的\u弱
引用,以便在块内使用
像这样:
__weak SomeObjectClass *weakSelf = self;
SomeBlockType someBlock = ^{
SomeObjectClass *strongSelf = weakSelf;
if (strongSelf == nil)
{
// The original self doesn't exist anymore.
// Ignore, notify or otherwise handle this case.
}
else
{
[strongSelf someMethod];
}
};
请参见“块”部分的此处:问题在于代理。我使用了,它对代理做了一些古怪的事情,所以我需要先去掉它。在我的
视图中将消失选择器中执行此操作可防止它们被保留:
- (void) viewWillDisappear:(BOOL)animated { /* or dealloc */
[super viewWillDisappear:animated];
_bridge = nil;
//UIWebView #1
[webView removeFromSuperview];
webView.delegate = nil; webView = nil;
//UIWebView #2
[textView removeFromSuperview];
textView.delegate = nil; textView = nil;
}
不管怎样,谢谢你所有优秀的答案 问题是代表们。我使用了,它对代理做了一些古怪的事情,所以我需要先去掉它。在我的视图中将消失选择器中执行此操作可防止它们被保留:
- (void) viewWillDisappear:(BOOL)animated { /* or dealloc */
[super viewWillDisappear:animated];
_bridge = nil;
//UIWebView #1
[webView removeFromSuperview];
webView.delegate = nil; webView = nil;
//UIWebView #2
[textView removeFromSuperview];
textView.delegate = nil; textView = nil;
}
不管怎样,谢谢你所有优秀的答案 你为什么不这么做?NoRotateTabBarController*选项卡控制器=[[NoRotateTabBarController alloc]init];这就是我分配它的方式…?如果您澄清一下可能会有所帮助-我在您的代码中没有看到UIWebViews。另外,这意味着什么“OSX Safari的开发工具”?我认为这有点与众不同,因为我没听说过……桌面Safari附带了开发人员工具,允许您检查UIWebView,就像您在Safari中查看网页一样。还对其进行了编辑,以包括我如何创建UIWebView。@mattcurtis,为什么不简单地使用工具(分配工具)配置文件来检查UIWebView是否被解除分配?:-)你为什么不这么做?NoRotateTabBarController*选项卡控制器=[[NoRotateTabBarController alloc]init];这就是我分配它的方式…?如果您澄清一下可能会有所帮助-我在您的代码中没有看到UIWebViews。另外,这意味着什么“OSX Safari的开发工具”?我认为这有点与众不同,因为我没听说过……桌面Safari附带了开发人员工具,允许您检查UIWebView,就像您在Safari中查看网页一样。还对其进行了编辑,以包括我如何创建UIWebView。@mattcurtis,为什么不简单地使用工具(分配工具)配置文件来检查UIWebView是否被解除分配?:-)即使你回答了自己的问题,你也应该选择它,以便其他读者立即知道去哪里。@DavidH哇,我想当我最初回答这个问题时,它不会让我忘记的。谢谢。即使你回答了自己的问题,你也应该选择它,以便其他读者立即知道去哪里。@DavidH哇,我想当我最初回答这个问题时,它不会让我忘记的。谢谢