『ios』信号量引起的卡住主线程和崩溃问题

2021-02-25  本文已影响0人  butterflyer

关于信号量的文章有很多,但是遇到的这两个问题,也算是采坑了吧~记录一下。


image.png

要做一个关于不断进入直播间的这样一个需求。
需求是要求每个进入直播间的人都要展示进入直播间的动画。
围绕着如何卡住这个后面的人,我想起了信号量这个东西。

dispatch_semaphore_t _setBottom_globalInstancesLock;
dispatch_semaphore_t _darts_globalInstancesLock;
//执行QUEUE的Name
char * SETBOTTOM_QUEUE_NAME = "com.SetBottom_Semaphore.queue";

static void _AlertViewInitGlobal() {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _setBottom_globalInstancesLock = dispatch_semaphore_create(1);
    });
}

@implementation Aobject

+(void)initialize{
    [super initialize];
    _AlertViewInitGlobal();
}
+ (void)showWithMessageType:(ZLRTCMsgSemaphoreType)type showBlock:(void(^)(void))showBlock
{
    if (type == ZLRTCMsgSemaphoreType_SetBottom) {
        //位于非主线程 不阻塞
        dispatch_async(dispatch_queue_create(SETBOTTOM_QUEUE_NAME, DISPATCH_QUEUE_SERIAL), ^{
            //Lock
            dispatch_semaphore_wait(_setBottom_globalInstancesLock, DISPATCH_TIME_FOREVER);
            //保证主线程UI操作
            dispatch_async(dispatch_get_main_queue(), ^{
    //            [[[UIApplication sharedApplication] keyWindow] addSubview:self];
                showBlock();
            });
        });
    }
}
+ (void)dismissWithMessageType:(ZLRTCMsgSemaphoreType)type dismissBlock:(void(^)(void))dismissBlock
{

    if (type == ZLRTCMsgSemaphoreType_SetBottom) {

        dispatch_async(dispatch_queue_create(SETBOTTOM_QUEUE_NAME, DISPATCH_QUEUE_SERIAL), ^{
            //Release Lock
            dispatch_semaphore_signal(_setBottom_globalInstancesLock);
            
            dispatch_async(dispatch_get_main_queue(), ^{
                dismissBlock();
            });
        });
    }
}

创建一个异步串行队列,这样在一个新的队列中去处理这个卡住后面进来的人,从而实现按顺序执行的问题。想法很美好,但现实很骨感。

第一个问题。

刚开始把信号量作为私有变量放到消息互动区。
这样就会出现在切换下个直播间,当前消息互动区被释放掉的时候,还处于wait状态,导致崩溃问题。原本以为在dealloc的时候,发送signal可以解决这个问题,实际上还是会崩溃。

第二个问题。

在上面我把信号量放到消息互动区的对象上,不能实现需求之后,我又想到能否放到单例中,来实现这个问题。
刚开始确实没有问题,但当直播间人数突然激增,或者是直播半小时以上,人数不断累积到6000+的时候,就会发生卡主主线程,只能听到声音的情况。
通过检测内存发现,在卡主之前,内存很平稳,不断wait不断signal,相互配合很好。
但一段时间之后,卡主主线程,那么内存就在不断的增大中。
经过压力测试,如果一秒钟发送几千条消息,那么信号量就会一直卡主,从而卡主主线程。
这算是一个坑吧。希望看到这个文章的人可以避免这个坑。

说一下最后问题的解决,我觉得这个需求,最好简单点直接拿计时器来做,不断从数组中取,时间间隔为动画的时间长度。

上一篇下一篇

猜你喜欢

热点阅读