在项目中,有时手势滑动的时候,如果执行了其它操作,会有卡顿感的感觉,如果能在手势滑动时,不作处理,等到滑动完成后,在回调,卡顿感会好些,下面上代码。
//
// IDCAsyncRunloop.h
//
// Copyright © 2018年 idol_ios. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface IDCAsyncRunloop : NSObject
+ (void)registerInMainRunloopObserver;
+ (void)addTransactionContainer:(void (^)())block;
@end
//
// IDCAsyncRunloop.m
// Copyright © 2018年 idol_ios. All rights reserved.
//
#import "IDCAsyncRunloop.h"
@implementation IDCAsyncRunloop{
}
static NSHashTable* sContainerFuns = nil;
+ (NSHashTable*)containerFuns{
return sContainerFuns;
}
static void _transactionRunLoopObserverCallback(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info)
{
@synchronized([IDCAsyncRunloop class]) {
for (void (^block)() in [IDCAsyncRunloop containerFuns]) {
if (block) {
block();
}
}
[[IDCAsyncRunloop containerFuns] removeAllObjects];
}
}
+ (void)addTransactionContainer:(void (^)())block
{
@synchronized(self) {
if (sContainerFuns == nil) {
sContainerFuns = [NSHashTable hashTableWithOptions:NSPointerFunctionsObjectPointerPersonality];
}
[sContainerFuns addObject:block];
}
}
+(void)registerInMainRunloopObserver{
static CFRunLoopObserverRef observer;
NSAssert([NSThread isMainThread], @"[IDCAsyncRunloop registerInMainRunloopObserver] must be used in main thread.");
// defer the commit of the transaction so we can add more during the current runloop iteration
CFRunLoopRef runLoop = CFRunLoopGetCurrent();
CFOptionFlags activities = (kCFRunLoopBeforeWaiting | // before the run loop starts sleeping
kCFRunLoopExit); // before exiting a runloop run
CFRunLoopObserverContext context = {
0,
NULL,
NULL,
NULL
};
observer = CFRunLoopObserverCreate(kCFAllocatorDefault, // allocator
activities, // activities
YES, // repeats
INT_MAX, // order after CA transaction commits
&_transactionRunLoopObserverCallback, // callback
&context); // context
CFRunLoopAddObserver(runLoop, observer, kCFRunLoopDefaultMode);
}
@end
------------------------
调用方法,
1 :在Appdelegate中的didFinishLaunchingWithOptions调用:
[IDCAsyncRunloop registerInMainRunloopObserver];
2:正式的调用示例,如在ASIHttpRequest框架中,请求数据
// 3.创建操作对象
AFHTTPRequestOperation *operation = [client HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
[IDCAsyncRunloop addTransactionContainer:^{
//在这里处理responseObject数据
}];
.........