【问题标题】:didreceivememorywarnings message sent to deallocated instancedidreceivememorywarnings 消息发送到释放的实例
【发布时间】:2013-08-30 18:21:22
【问题描述】:

在我的应用中,如果我有一个视图已被释放(通过模式关闭或导航堆栈弹出),然后我收到内存警告,我的应用就会崩溃。

我已经通过在我的应用程序中很早就放置一个模态创建/关闭进行测试,如下所示:

WWebViewController *webViewController = [[WWebViewController alloc] initWithPath:@"http://www.google.com"];
        [webViewController setIsModal:YES];
        WMainNavController *navController = [[WMainNavController alloc] initWithRootViewController:webViewController];
        [self presentViewController:navController animated:YES completion:nil];

网页视图非常简单:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self setNavigationDefaultsWithTitle:@"Loading..." withBackButton:YES withSearchButton:YES deepLinked:false];
    webView = [[UIWebView alloc] initWithFrame:[self.view bounds]];
    webView.delegate = self;
    [self.view addSubview:webView];
    [webView scalesPageToFit];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.path]]];
    [self showNoConnectionImageIfNecessary:NO];
    // Do any additional setup after loading the view.
}

...

- (void)dealloc {
    [webView loadHTMLString:@"" baseURL:nil];
    [webView stopLoading];
    [[NSURLCache sharedURLCache] removeAllCachedResponses];
    [webView setDelegate:nil];
    webView = nil;
}

但是,简单地呈现然后关闭此视图,然后模拟内存警告会给出:

*** -[WMainNavController retain]: message sent to deallocated instance 0xba953c0

我尝试过直接调用 WWebViewController 而不使用 WMainNavController,尝试使用常规导航控制器,尝试简单地将某些内容推送到导航堆栈。如果我在应用程序的任何位置弹出或关闭视图,它总是会崩溃。

我在做一些根本错误的事情吗?如果我在不关闭/弹出的情况下通过应用程序,它可以很好地处理内存警告,并且在此之前只有一个屏幕将此屏幕显示为模式并且是程序的根视图。

我会提供任何需要的额外信息,有人见过这样的吗?

编辑 -- 这是一个 ARC 实现。

编辑 -- 这是我的带有僵尸的乐器的屏幕截图:

在我看来一切都很正常。它在解雇时正确解除分配,但由于某种原因,内存警告调用正试图访问该视图控制器。我完全不知所措。

【问题讨论】:

  • 抱歉,这是 ARC。我将在其中进行编辑。
  • 如果您在dealloc 中取出所有额外的webView 呼叫,您是否看到此问题?通常,您不应在解除分配的过程中启动新的异步加载(如 loadHTMLString:baseURL: 所做的那样)。
  • dealloc 方法中的大部分内容是我在释放 webView 时处理内存问题的东西。愚蠢的事情总是试图留在记忆中。但是,无论我关闭/弹出什么视图,都会发生这种崩溃,它不一定是这个特定的 web 视图(或者一个 web 视图,可以是任何视图控制器)。要直接回答你的问题,是的,如果我在我的 dealloc 方法中删除所有这些东西,它仍然会发生。
  • 通常在内存不足的情况下,应用程序将“释放”任何“未”使用的视图,例如如果它是当前视图。因此,尝试访问其中一个视图中的任何内容而不再次显式实例化它会导致崩溃。您可以尝试在 viewWillUnload 中卸载缓存:但这可能不是它崩溃的原因。调试器说明了一切......您在 WMainNavController 或 WMainNavController 本身消失后尝试访问它。是 0xba953c0 WMainNavController 吗?试试 po 0xba953c0 看看它说了什么。
  • @HubertKunnemeyer Apps 倾向于在 iOS6 之前做到这一点,但从那以后就没有了。我应该说我的应用程序仅针对 iOS6 及更高版本,其中 viewDidUnload 已被弃用。似乎在我的应用程序的某个地方,某处保留了所有已分配或某物的快照,并且 didReceiveMemoryWarning 注意到了这一点,但仪器显示 WWebViewController 和 WMainNavController 在此发生之前都已完全解除分配。

标签: ios memory-management didreceivememorywarning


【解决方案1】:

对于遇到类似问题的任何人,我无法真正解释如何解决它,但我可以告诉你我做了什么让我的问题神奇地消失了。

我基本上开始在我的目标的构建阶段从编译源中删除任何影响我的应用程序的许多或所有其他主要组件的类别/控制器/任何东西。然后我相应地注释掉了代码,这样我的应用程序就可以构建到我需要它去测试的地方。最终,我隔离了一个“导致问题”的 UIViewController 类别,并从中删除了所有方法以及一个 NSString 外部变量。

这解决了问题,但是当我试图找出是什么方法导致它时......结果没有一个。当我取消注释所有内容并回到我开始的类别时,它继续工作,不再崩溃。

我很高兴它现在可以正常工作,但我很困惑,我永远不会真正知道它为什么一开始就坏了。

【讨论】:

    猜你喜欢
    • 2012-08-22
    • 1970-01-01
    • 2016-08-28
    • 2011-06-16
    相关资源
    最近更新 更多