美文网首页
[[NSRunLoop currentRunLoop] run]

[[NSRunLoop currentRunLoop] run]

作者: who_young | 来源:发表于2023-05-26 12:03 被阅读0次

    总结:
    一旦在子线程调用了 [[NSRunLoop currentRunLoop] run] 方法,那么在这个方法下的代码就永远无法执行到。若要继续往下执行代码,可使用 [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:seconds]] 方法代替。
    参考文献:子线程上的RunLoop运行循环

    Tip: @synchronized 的底层实现是使用了 recursive_mutex_t。

    - (void)startTimer {
        self.timerThread = [[NSThread alloc] initWithTarget:self selector:@selector(createTimer) object:nil];
        [self.timerThread start];
    }
    
    // 加锁方式:在子线程上的启用RunLoop
    - (void)createTimer {
    //    方法一:该方法会死锁
        @synchronized (self) {
            if (self.heartbeatTimer) {
                [[NSRunLoop currentRunLoop] addTimer:self.heartbeatTimer forMode:NSRunLoopCommonModes];
                [[NSRunLoop currentRunLoop] run];
            }
        }
        
        NSRecursiveLock *recLock = [[NSRecursiveLock alloc] init];
    //    方法二:该方法会死锁
        [recLock lock];
        if (self.heartbeatTimer) {
            [[NSRunLoop currentRunLoop] addTimer:self.heartbeatTimer forMode:NSRunLoopCommonModes];
            [[NSRunLoop currentRunLoop] run]; // 调用这个方法,会开启子线程的运行循环,不会停止,下面👇🏻的代码就始终执行不到了。
            // [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:60]]; // 调用这个方法,会开启子线程的运行循环,不会停止,直到 60s 后退出循环,在 60s 过后,下面👇🏻的代码才会执行。
            [recLock unlock];
        }
        
    //    方法三:该方法不会死锁
        [recLock lock];
        if (self.heartbeatTimer) {
            [[NSRunLoop currentRunLoop] addTimer:self.heartbeatTimer forMode:NSRunLoopCommonModes];
            [recLock unlock]; // 在 [[NSRunLoop currentRunLoop] run] 方法前解锁,避免死锁。
            [[NSRunLoop currentRunLoop] run];
        }
    }
    

    相关文章

      网友评论

          本文标题:[[NSRunLoop currentRunLoop] run]

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