弹出视图控制器时崩溃

时间:2014-05-30 13:57:09

标签: ios objective-c uiviewcontroller webview

我有一个视图控制器(让它称之为ViewController)在其代码中带有计时器,并有另一个视图控制器(让它称之为ContentViewController),其中包含webView,根据哪个按钮显示内容点击。

我在ViewController上有按钮,当点击它时,推送ContentViewController,它将一个html文件加载到它的webView中。

如果推送了ContentViewController,则定时器用于关闭它。

以下是我创建计时器的方法:

-(void)createTimer :(NSNumber*)index
{
if (_show)
{
    NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:index, @"parameter1", nil];
    switch ([index intValue])
    {
        case 1001:
            [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(updateUi:) userInfo:dictionary repeats:YES];
            break;
        case 1002:
            [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(updateUi:) userInfo:dictionary repeats:YES];
            break;
        case 1003:
            [NSTimer scheduledTimerWithTimeInterval:20.0 target:self selector:@selector(updateUi:) userInfo:dictionary repeats:YES];
            break;
        case 1004:
            [NSTimer scheduledTimerWithTimeInterval:20.0 target:self selector:@selector(updateUi:) userInfo:dictionary repeats:YES];
            break;
    }
}
}

这里是ViewController中的代码,它在计时器触发时关闭ContentViewController:

-(void)updateUi :(NSTimer *)timer
{
int  index = [[timer.userInfo objectForKey:@"parameter1"] intValue];

if([self.navigationController.visibleViewController isKindOfClass:[ContentViewController class]])
{
    if ([[[NSUserDefaults standardUserDefaults]valueForKey:@"CurrentString"] intValue]==index )
    {
        [self.navigationController popViewControllerAnimated:YES];
    }
}
}

在ContentViewController上显示的网页上有一个按钮,当用户点击它时,ContentView必须返回到ViewController。以下是我如何做到这一点:

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
NSURL *URL = [request URL];
if ([[URL scheme] isEqualToString:@"coffee-drink"])
{
    NSString *urlString = [[request URL] absoluteString];
    NSArray *urlParts = [urlString componentsSeparatedByString:@":"];

    if (urlParts.count > 1)                          ///------------поменял
    {
        [self.navigationController popViewControllerAnimated:YES];
    }
}

return YES;
}    

以上所有方法都可以正常工作,但有时它会因以下错误而崩溃:

[ContentViewController respondsToSelector:]: message sent to deallocated instance

而且,我还有其他错误:

  

嵌套推送动画可能导致导航栏损坏

     

在意外状态下完成导航转换。导航栏子视图树可能已损坏。

  

委托(webView:decisionPolicyForNavigationAction:request:frame:decisionListener :)等待10秒后无法返回

最后一个很少出现。 我不知道我做错了什么。有人可以帮助我吗?如果需要,我会提供更多信息!提前致谢!

3 个答案:

答案 0 :(得分:1)

问题

您正在弹出视图,而不会让ARC通过保持活动来释放所有对象和委托。

我的解决方案

适用于NSTimer

在@implementation中创建NSTimer *timer并在想要初始化时使用它。要在弹回时正确解除锁定,请在viewWillDisappear设置[timer invalidate]timer = nil

代表

将特定代表设为nil。例如self.delegate = nil

答案 1 :(得分:0)

@Yuandra Ismiraldi是对的。您的NSTimer会每隔20/10秒重复调用updateUI方法,直到收到[timer invalidate];条指令。当您浏览视图控制器树时,您将收到此错误消息。有时您的NavigationViewController将需要更多内存并释放一些未使用的对象。在您的情况下,一些先前显示的视图控制器仍然每20/10秒运行updateUI方法。一旦释放了该视图控制器并且调用了您的选择器,您将收到此崩溃。

我希望这可以解释为什么有时会发生这种崩溃,有时候不会。

答案 2 :(得分:-1)

您的计时器代码

  

[NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(updateUi :) userInfo:dictionary repeats:YES]

repeat参数设置为YES,这使得您的计时器始终重复,因此在计时器第一次运行并且视图弹出后重复发送消息updateUI,从而导致您的错误。要确保您的计时器只运行一次,请将repeat设置为NO

[NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(updateUi:) userInfo:dictionary repeats:NO]