2

在使用 ARC 时,我的旧 UIWebViews 似乎仍然存在,出于某种原因,即使在我退出他们的 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];

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 中进行检查时,旧的 UIWebViews 似乎在堆积,而旧的 UIWebViews 仍然显示在菜单中。这是 Safari 开发者工具中的错误吗?有没有办法确保我的 UIWebViews 被释放?

4

3 回答 3

3

问题是代表。我正在使用WebViewJavascriptBridge,它对代表做了一些时髦的事情,所以我需要先摆脱它。在我的选择器中这样做viewWillDisappear可以防止它们被保留:

- (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;
}

无论如何,感谢您提供的所有出色答案!

于 2013-05-02T23:38:11.650 回答
1

一般来说,当你体验到这一点时,你会发现有些东西正在保留观点。将断点或日志消息添加到所有自定义子类的 dealloc 方法中,并查看它们是否正在被 dealloc 处理。如果是这样,并且其中之一是 UIWebViews 的所有者,那么您将不得不挖掘。

如果您只是卡住并且无处可去,那么复制您的应用程序(整个文件夹),并在上面的代码中摆脱所有复杂的类(一个接一个)并使用一个简单的 UIViewController 子类,并在 dealloc 中使用日志消息。使用非常简单的类,您应该能够获得项目,因此所有内容都可以解除。他们开始将您的自定义类一一放回,直到 dealloc 停止。这应该可以帮助您缩小问题所在。

您可能知道,阻止保留周期或使用强委托可能会导致问题。我确实注意到 UIWebView 明确指出,如果您正在使用委托,则应在处理委托之前将其设置为 nil。[NSURLConnection 也保留了委托。]

于 2013-05-02T21:47:48.733 回答
0

self.window.rootViewController由于您在动画块中的引用,您似乎有一个保留周期。

使用 ARC,块被复制,因此也捕获了您在块内使用的变量。所以你需要创建一个__weak对 self 的引用以在你的块中使用。

像这样:

__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];
    }
};

请参阅此处的块部分:ARC 最佳实践

于 2013-05-02T21:48:21.063 回答