2

私の古いUIWebViewは、ARCを使用しているときに残っているようです.何らかの理由で、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 で調べると、古い UIWebView が積み重なっているように見え、古い UIWebView がまだメニューに表示されていることに気付きました。これは 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 されているかどうかを確認します。もしそうなら、そのうちの 1 人が UIWebViews の所有者である場合は、掘り下げる必要があります。

単純に立ち往生してどこにも行けない場合は、アプリ (フォルダー全体) を複製し、上記のコードですべての複雑なクラスを (1 つずつ) 取り除き、単純な UIViewController サブクラスを使用して、dealloc のログ メッセージを使用します。非常に単純なクラスを使用すると、プロジェクトを取得できるため、すべてが解放されます。dealloc が停止するまで、カスタム クラスを 1 つずつ元に戻し始めます。これは、問題がどこにあるかを絞り込むのに役立ちます。

おそらくご存じのとおり、保持サイクルをブロックしたり、強力なデリゲートを使用したりすると、問題が発生する可能性があります。UIWebView は、デリゲートを使用している場合は、破棄する前にデリゲートを nil に設定する必要があると明示的に述べていることに気付きました。[また、NSURLConnection はデリゲートを保持します。]

于 2013-05-02T21:47:48.733 に答える
0

self.window.rootViewControllerアニメーション ブロックでの参照が原因で、保持サイクルが発生しているようです。

ARC では、ブロックがコピーされるため、ブロック内で使用する変数もキャプチャされます。__weakしたがって、ブロック内で使用するために自己への参照を作成する必要があります。

そのようです:

__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 に答える