Iphone ARC-UIWebView/UIViewController是否在内存中停留?

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

在使用ARC时,我的旧UIWebView似乎仍然存在,出于某种原因,即使在我离开他们的UIViewController之后,它们仍然会出现在OSX Safari的开发工具中

我正在将转换分配给包含UIWebView的视图控制器,如下所示:

    //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哇,我想当我最初回答这个问题时,它不会让我忘记的。谢谢