- 线程保活(参考YYWebImageOperation)
+ (void)_networkThreadMain:(id)object {
@autoreleasepool {
[[NSThread currentThread] setName:@"com.ibireme.yykit.webimage.request"];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
[runLoop run];
}
}
+ (NSThread *)_networkThread {
static NSThread *thread = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
thread = [[NSThread alloc] initWithTarget:self selector:@selector(_networkThreadMain:) object:nil];
if ([thread respondsToSelector:@selector(setQualityOfService:)]) {
thread.qualityOfService = NSQualityOfServiceBackground;
}
[thread start];
});
return thread;
}
- 监测卡顿
- (void)beginMonitor {
_semaphore = dispatch_semaphore_create(0)
CFRunLoopObserverContext context = {0, (__bridge void *)self, NULL, NULL, NULL}
_observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopAllActivities, true, 0, myCFRunLoopObserverCallBack, &context)
CFRunLoopAddObserver(CFRunLoopGetMain(), _observer, kCFRunLoopCommonModes)
dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{
while (1) {
intptr_t result = dispatch_semaphore_wait(self->_semaphore, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_MSEC * 20))
if (result != 0) {
if (!self->_observer) {
self->_semaphore = 0
self->_activity = 0
self->_timeoutCount = 0
return
}
// 为什么是监测kCFRunLoopBeforeSources和kCFRunLoopAfterWaiting这两种状态?因为:
// 1、source1和timer都是在kCFRunLoopAfterWaiting之后执行
// 2、source0是在kCFRunLoopBeforeSources之后执行
// 3、source0和source1同时存在时,在kCFRunLoopBeforeSources之后先执行source0再执行source1
if (self->_activity == kCFRunLoopBeforeSources || self->_activity == kCFRunLoopAfterWaiting) {
if (++self->_timeoutCount < 3) { // count从1开始比较,count=3时执行下面语句,正好三次
continue
}
// TODO: 卡顿上报
}
}
self->_timeoutCount = 0
}
})
}
void myCFRunLoopObserverCallBack(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) {
ViewController *vc = (__bridge ViewController *)info
vc->_activity = activity
dispatch_semaphore_signal(vc->_semaphore)
}
- 性能优化(参考YYTransaction)
static void YYTransactionSetup() {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
transactionSet = [NSMutableSet new];
CFRunLoopRef runloop = CFRunLoopGetMain();
CFRunLoopObserverRef observer;
observer = CFRunLoopObserverCreate(CFAllocatorGetDefault(),
kCFRunLoopBeforeWaiting | kCFRunLoopExit,
true,
0xFFFFFF,
YYRunLoopObserverCallBack, NULL);
CFRunLoopAddObserver(runloop, observer, kCFRunLoopCommonModes);
CFRelease(observer);
});
}
- UITableView滑动优化
// tableView滑动停止才会执行
[self performSelector:@selector(setCellImage:) withObject:cell afterDelay:0 inModes:@[NSDefaultRunLoopMode]]
- (void)setCellImage:(MyTableViewCell *)cell {
NSString *path = [[NSBundle mainBundle] pathForResource:@"mypic" ofType:@"jpg"]
cell.imgView.image = [UIImage imageWithContentsOfFile:path]
}
- crash防护
CFRunLoopRef runLoop = CFRunLoopGetCurrent();
CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop);
while (true) {
for (NSString *mode in (__bridge NSArray *)allModes) {
CFRunLoopRunInMode((CFStringRef)mode, 0.001, false);
}
}
未完待续。。。