This commit is contained in:
DDIsFriend
2023-08-23 09:24:40 +08:00
parent 6bd037c5dd
commit 63ca919ed5
494 changed files with 35308 additions and 6623 deletions

View File

@@ -0,0 +1,147 @@
//
// Example
// man
//
// Created by man 11/11/2018.
// Copyright © 2020 man. All rights reserved.
//
#import "_RunloopMonitor.h"
#import "_BacktraceLogger.h"
//
static int64_t const OUT_TIME = 100 * NSEC_PER_MSEC;
// before wait
static NSTimeInterval const WAIT_TIME = 0.5;
@interface _RunloopMonitor () {
@public
CFRunLoopObserverRef observer;
CFRunLoopActivity currentActivity;
dispatch_semaphore_t semaphore;
BOOL isMonitoring;
}
@end
static void runloopObserverCallback(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) {
//_RunloopMonitor * monitor = (__bridge _RunloopMonitor*)info;
[_RunloopMonitor shared]->currentActivity = activity;
// switch (activity) {
// case kCFRunLoopEntry:
// NSLog(@"##### %@", @"kCFRunLoopEntry");
// break;
// case kCFRunLoopBeforeTimers:
// NSLog(@"##### %@", @"kCFRunLoopBeforeTimers");
// break;
// case kCFRunLoopBeforeSources:
// NSLog(@"##### %@", @"kCFRunLoopBeforeSources");
// break;
// case kCFRunLoopBeforeWaiting:
// NSLog(@"##### %@", @"kCFRunLoopBeforeWaiting");
// break;
// case kCFRunLoopAfterWaiting:
// NSLog(@"##### %@", @"kCFRunLoopAfterWaiting");
// break;
// case kCFRunLoopExit:
// NSLog(@"##### %@", @"kCFRunLoopExit");
// break;
// default:
// break;
// }
dispatch_semaphore_t sema = [_RunloopMonitor shared]->semaphore;
dispatch_semaphore_signal(sema);
}
@implementation _RunloopMonitor
+ (instancetype)shared {
static id ins = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
ins = [[super allocWithZone:NSDefaultMallocZone()] init];
});
return ins;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
return [self shared];
}
- (void)dealloc {
[self endMonitor];
[super dealloc];
}
- (void)beginMonitor {
if ([_RunloopMonitor shared]->isMonitoring) return;
[_RunloopMonitor shared]->isMonitoring = YES;
//
CFRunLoopObserverContext context = {
0,
(__bridge void*)self,
&CFRetain,
&CFRelease,
NULL
};
//static CFRunLoopObserverRef observer;
observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, 0, &runloopObserverCallback, &context);
// 线
CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopCommonModes);
// 线
semaphore = dispatch_semaphore_create(0); //?
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// loop
while ([_RunloopMonitor shared]->isMonitoring) {
if ([_RunloopMonitor shared]->currentActivity == kCFRunLoopBeforeWaiting)
{
//
__block BOOL timeOut = YES;
dispatch_async(dispatch_get_main_queue(), ^{
timeOut = NO; // timeOut
});
[NSThread sleepForTimeInterval:WAIT_TIME];
// WAIT_TIME , timeOut , 线
if (timeOut) {
[_BacktraceLogger cocoadebug_logMain];
}
}
else
{
// Timer,Source,
// ,result=0, result!=0
long result = dispatch_semaphore_wait([_RunloopMonitor shared]->semaphore, dispatch_time(DISPATCH_TIME_NOW, OUT_TIME));
if (result != 0) { //
if (![_RunloopMonitor shared]->observer) {
[[_RunloopMonitor shared] endMonitor];
continue;
}
if ([_RunloopMonitor shared]->currentActivity == kCFRunLoopBeforeSources ||
[_RunloopMonitor shared]->currentActivity == kCFRunLoopAfterWaiting ||
[_RunloopMonitor shared]->currentActivity == kCFRunLoopBeforeTimers) {
[_BacktraceLogger cocoadebug_logMain];
}
}
}
}
});
}
- (void)endMonitor {
if (!observer) return;
if (!isMonitoring) return;
isMonitoring = NO;
CFRunLoopRemoveObserver(CFRunLoopGetMain(), observer, kCFRunLoopCommonModes);
CFRelease(observer);
observer = nil;
}
@end