首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UIWebView - CFData何时(或如何)发布?

UIWebView - CFData何时(或如何)发布?
EN

Stack Overflow用户
提问于 2010-10-20 22:55:21
回答 3查看 2.1K关注 0票数 14

几天后,我的头撞在墙上,睡不着觉,我希望能在这里找到一些帮助。我在这里看过很多帖子,但似乎没有任何一个答案能为我提供解决方案。

简而言之,我的问题是,我的应用程序在大量使用UIWebView (>10分钟)后崩溃(例如,一个接一个地打开更大的新闻报纸站点)。

为了提供更多细节:我正在编写一个iPhone应用程序,而在MainViewController上,我在navigationController上推一个browserViewController。browserViewController加载一个包含UWebView的nib (我不通过编程创建WebView )。UIWebView是使用接口生成器连接起来的。

当返回Main,然后再返回到browserViewController时,我只在browserViewController为零的情况下重新创建它。(我希望将加载的内容保留为UIWebView --只有当存在内存警告时,应该卸载此视图并释放所使用的所有内存)。

在这两种情况下,MainViewController和browserViewController都响应内存警告,但这似乎没有提供足够的缓解。

看一看仪器,我注意到,例如,CFData(商店)一直在增长。即使我模拟一个内存警告(请参阅下面的代码)并在browserViewController上调用browserViewController,CFData仍然是分配的,并且没有被释放。

所以我最大的问题是:

如何释放从“浏览”中创建的内存?

这包括两个案件:

-如何确保viewDidUnload适当地释放分配给我的CFData(存储)的内存?

-当用户一直在browserViewController中加载页面时如何释放内存?

谁管理CFData?

有关我的简化示例代码,请参见下面的代码:

MainViewController.h

代码语言:javascript
复制
//  MainViewController.h
#import "myAppDelegate.h"
#import "BrowserViewController.h"

@interface MainViewController : UIViewController {
    BrowserViewController *browViewController;
}

- (void) switchToBrowserViewController;

@end

MainViewController.m

代码语言:javascript
复制
//  MainViewController.m
#import "MainViewController.h"

@implementation MainViewController

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    [browViewController release];
    browViewController = nil;
}

- (void)viewDidUnload {
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)dealloc {
    [browViewController release];
    browViewController = nil;
    [super dealloc];
}

- (void) switchToBrowserViewController {

    // create new browViewController if needed
    if ( browViewController == nil ) {
        browViewController = [[BrowserViewController alloc]     initWithNibName:@"BrowserViewController" bundle:nil];
    }

    browViewController.navigationItem.hidesBackButton = YES;

    [((myAppDelegate *)[UIApplication sharedApplication].delegate).navController setNavigationBarHidden:YES animated:NO];

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration: 1];
    [UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:
  ((myAppAppDelegate *)[UIApplication sharedApplication].delegate).navController.view cache:YES];

    [((myAppAppDelegate *)[UIApplication sharedApplication].delegate).navController pushViewController:browViewController animated:NO];
    [UIView commitAnimations];

}

@end

BrowserViewController.h

代码语言:javascript
复制
//  BrowserViewController.h

#import <UIKit/UIKit.h>
#import "myAppDelegate.h"

@interface BrowserViewController : UIViewController <UIWebViewDelegate> {
    IBOutlet UITextField *browserURLField;
    IBOutlet UIWebView *browserWebView;
}

@property (nonatomic, retain) UIWebView *browserWebView;

- (void) loadURLinBrowser;

@end

BrowserViewController.m

代码语言:javascript
复制
//  BrowserViewController.m
#import "BrowserViewController.h"

@implementation BrowserViewController
@synthesize browserWebView;

- (void)viewDidLoad {
    [browserWebView setDelegate:self];
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
}

- (void)viewDidUnload { 
    [super viewDidUnload];

    [browserWebView stopLoading];
    [browserWebView setDelegate:nil];
    [browserWebView removeFromSuperview];
    [browserWebView release];
    browserWebView = nil;

    browserURLField = nil;
}

- (void)dealloc {
    [browserURLField release];

    browserWebView.delegate = nil;
    [browserWebView stopLoading];
    browserWebView = nil;
    [browserWebView release];

    [super dealloc];
}

- (void) switchBackToMainViewController {

    [((myAppDelegate *)[UIApplication sharedApplication].delegate).navController setNavigationBarHidden:NO animated:NO];

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration: 1];
    [UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:((myAppAppDelegate *)[UIApplication sharedApplication].delegate).navController.view cache:YES];

    [((myAppAppDelegate *)[UIApplication sharedApplication].delegate).navController popViewControllerAnimated:NO];

    [UIView commitAnimations];
}

- (void) loadURLinBrowser {
    NSURL *url = [[NSURL alloc] initWithString:browserURLField.text];
    NSMutableURLRequest *request = [[NSURLRequest alloc] initWithURL: url];
    [browserWebView loadRequest: request];
    [request release];
    [url release];
}

@end

我曾尝试过其他职位的各种建议。例如:

  • 1)将空页加载到WebView中。baseURL:nil;
  • 2) *html =@“;browserWebView loadHTMLString:loadHTMLString:loadHTMLString使用removeAllCachedResponses在上述代码中的不同位置[NSURLCache sharedURLCache setSharedURLCache也没有提供帮助(我在AppDelegate applicationDidFinishLaunching中也使用了这个)。”NSURLCache *sharedCache = [NSURLCache alloc initWithMemoryCapacity:0磁盘容量:0磁盘路径:0];NSURLCache setSharedURLCache: sharedCache;sharedCache发布;

不幸的是,所有这些都无助于“清除缓存”或释放由CFData(存储)分配的内存。

如果有人能给我一些启示,让我知道我错过了什么或者做错了什么,我会非常感激的。

编辑:

在KiwiBastard的最初回复之后,我添加了一个屏幕截图,显示了我在“仪器”中观察到的情况:

2010年6月编辑:

我还没能解决这个问题。

在第二次尝试中,我完全以编程的方式创建了UIWebView。

还是一样的问题。然而,我注意到了一种奇怪的行为。例如,如果我将一个PDF文档加载到webView中,并且不上下滚动PDF页面,则webView & data将被成功释放。然而,一旦我滚动到第二页,dealloc就不能再工作了,我的应用程序在某个时候会耗尽内存。这是完全奇怪的,我无法解决这个问题。

有人知道吗?帮助?

EN

回答 3

Stack Overflow用户

发布于 2011-07-25 12:11:26

要发布CFRelease(your CFData ,只需调用CFData object name).即可。

票数 2
EN

Stack Overflow用户

发布于 2010-10-20 23:16:48

我认为可能发生的情况是,您的浏览器从未被释放,而且viewDidUnload可能从未被调用过。

因为您的MainViewController有一个从未发布过的BrowserViewController类型的变量,所以它将驻留在应用程序的生命周期中。另外,由于您只是在切换视图,视图也将保留在内存中。

我可以建议您在需要时尝试创建BrowserViewController变量,并在导航控制器按下之后释放它吗?

代码语言:javascript
复制
 BrowserViewController *browViewController = [[BrowserViewController alloc]     initWithNibName:@"BrowserViewController" bundle:nil];

 browViewController.navigationItem.hidesBackButton = YES;

 [((myAppDelegate *)[UIApplication sharedApplication].delegate).navController setNavigationBarHidden:YES animated:NO];

 [UIView beginAnimations:nil context:NULL];
 [UIView setAnimationDuration: 1];
 [UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:
  ((myAppAppDelegate *)[UIApplication sharedApplication].delegate).navController.view cache:YES];

 [((myAppAppDelegate *)[UIApplication sharedApplication].delegate).navController pushViewController:browViewController animated:NO];
 [UIView commitAnimations];
 [browViewController release];

我知道它会轻微地影响性能,因为它每次都要加载nib,但是您显然不想缓存vc?

票数 1
EN

Stack Overflow用户

发布于 2012-02-18 05:24:29

在我读过的某个地方,这是一个众所周知的UIWebView bug。有人说要使用静态的webview对象来避免一次又一次地初始化它,但是找不到合适的解决方案。即使你也遵循同样的方法。幸运的是,我的需求是一个带有图像的普通web视图。因此,我最终使用了一个带有UIImageView和UITextView的自定义控制器,而无需编辑。对我来说很好。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3982955

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档