放在下一个runloop执行,保证当前执行正确

标签: runloop
457人阅读 评论(0) 收藏 举报
分类:

遇到的问题是:播放下一个视频的时候,一直loading,研究了一下,使用下一个runloop解决
这里说一下视频播放的流程:
1. 获取视频地址URL
2. 根据URL获取视频缓冲
3. 当缓冲ok的时候,判断播放器state状态,当state == active的时候可以播放,stat = stop的时候不能播放。
下面从视频播放完成playToEnd开始说起:

/*视频播放完,开始下个视频播放*/
-(void)playToEnd {
    state = active;/*播放器state需要是active的,如果是stop的情况就不播放下一个视频了。这里预设state是active*/
    playNextVideo(state); 
    state = stop;/*由于playNextVideo用到了state,该行不能放到method之上*/
}

/*播放下一个视频*/
-(void) playNextVideo:(state ){
    /*异步联网操作,获取视频url地址.前提是state = active*/
    if(state == active){
        [NetWrok connectNetwork:^{
            startLoad();
        }];
    }
}

/*异步联网操作,根据地址获取一定缓冲*/
-(void) startLoad{
    state = active;
    startBuffer();
}

/*缓冲完成,开始播放画面*/
-(void) onBufferOK{
    if(state = active){
        play();
    }
}

正常逻辑:
看调用playNextVideo(state)这一行(第4行),由于这个函数获取视频url地址是异步的,程序会先执行state=stop。然后网络应答后再调用startLoad,此时state=active;今儿onBufferOK函数,也能调用play函数了;
出问题逻辑:
[NetWrok connectNetwork^{}}在由缓冲的情况下,不发起实际的网络请求。立即应答,导致startLoad立即被调用。然而第5行执行state=stop了。最后即便onBufferOK调用,但是state还是stop状态,并么有调用play函数。程序state 死锁了。
    
解决办法就是:
 在调用startLoad的那行加放到下一个runloop执行。保证playToEnd函数的第5行 state=stop先执行。代码如下:

/*播放下一个视频*/
-(void) playNextVideo:(state ){
    /*异步联网操作,获取视频url地址.前提是state = active*/
    if(state == active){
        [NetWrok connectNetwork:^{
            /*放到下一个runloop执行*/
            dispatch_async(dispatch_get_main_queue(),^{
                startLoad();
            });
        }];
    }
}

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:958532次
    • 积分:7666
    • 等级:
    • 排名:第2760名
    • 原创:163篇
    • 转载:44篇
    • 译文:16篇
    • 评论:112条
    博客专栏
    最新评论