美文网首页
【问题】WebView\\NSTimer引发的一个异步处理问题

【问题】WebView\\NSTimer引发的一个异步处理问题

作者: 狂暴火鸡 | 来源:发表于2015-08-11 20:12 被阅读180次

    问题:
    当前有一个场景,当WebView接受数据的时候会触发回调,从而触发一段特定逻辑,该特定逻辑是通过NSTimer延迟触发一段与WebView相关的代码,详细请看以下的代码块:

    ... ///<WebView
    
    NSTimer* timer = nil;
    TestClass* obj;
    
    - (void)webViewDidFinishLoad:(UIWebView *)webView
    {
          [self.obj testFunction:webView];
    }
    
    ... ///<TestClass
    
    - (void)timerFunction:(UIWebView*)webView
    {
          [self cancelTimer]; ///<回收Timer
    
          timer = [NSTimer scheduledTimerWithTimeInterval:5 
                                                   target:self 
                                                 selector:@selector(dealWebView:) 
                                                 userInfo:webView repeats:NO]; ///<通过WebView创建Timer
    }
    
    - (void)cancelTimer
    {
          [timer invalidate];
          [timer release];
          timer = nil;
    }
    
    - (void)dealWebView:(NSTimer*)sender
    {
    ...
    }
    

    分析:
    这里存在一个问题,当webView发起第一次DidFinishLoad回调的时候,NSTimer创建后持有了一份WebView计数。在没有执行dealWebView函数的5秒内,若回收WebView,则导致NSTimer持有的WebView成为唯一一份计数。这时候若又来了DidFinishLoad,调用cancelTimer时,则会将WebView析构,从而导致往下的操作都是非法操作(野指针)。

    abc (1).png

    一般来说这种逻辑结构还是比较容易解决,但很多业务是放在DidFinishLoad这个回调的里面的更深函数堆栈,则很容易出现这种异步析构问题。
    根本的原因其实是webview在管理者release前,没有通知Timer进行析构,导致Timer持有了一份不安全的WebView。(为什么会是不安全?我们根据“谁创建谁析构”的原则可以知道,WebView不是NSTimer创建,但为了确保NSTimer执行安全,故需要持有WebView,而当WebView被管理者析构的时候,则该WebView无论是否被析构,都将处于无效状态。)
    解决:
    方案1:在webview中设置一个变量,标记WebView是否有效,如果无效则不处理timerFunction。
    方案2:将webview析构前,通知timer需要主动析构,回收timer持有的webview计数,再进行析构。

    讨论:
    其实还有很多案例,如当进行动画过程的时候作用于动画的视图被管理者析构了,动画结束后的回调可能需要对视图进行一些逻辑,但视图此时处在不安全状态,很容易产生Crash。关键是当管理者析构对象的时候,是否应该通知其他持有这个对象的拥有者对象失效呢?
    具体问题应该具体分析!
    视图正在做动画过程中,用户将视图removeFromSuperView,视图的生命周期并没有结束,而是由动画对应的block延续。视图可能会持有1. 强引用模块,如子视图 2. 弱引用模块,如数据源。对于第一种,则在视图真正dealloc的时候进行回收;对于第二种,则应该在管理者析构视图的时候,将弱引用提前致空,防止出现不安全的访问操作。在这个案例中,对象没有进行dealloc时,都应该处于生命周期中(内存泄露除外),则应该要保证对象所有逻辑合法安全。

    相关文章

      网友评论

          本文标题:【问题】WebView\\NSTimer引发的一个异步处理问题

          本文链接:https://www.haomeiwen.com/subject/dypiqttx.html