throttle
JunyiXie opened this issue · 0 comments
JunyiXie commented
#import "NSObject+JYThrottle.h"
#import <objc/runtime.h>
#import <objc/message.h>
#import "VKMsgSend.h"
static char XJYThrottle;
static char XJYThrottleQueue;
@implementation NSObject (JYThrottle)
- (void)xjy_performSelector:(SEL)aSelector error:(NSError *__autoreleasing *)error withThrottle:(NSTimeInterval)inteval,... {
va_list argList;
va_start(argList, error);
NSArray* boxingArguments = vk_targetBoxingArguments(argList, [self class], aSelector, error);
va_end(argList);
if (!boxingArguments) {
return ;
}
dispatch_async([self getSerialQueue], ^{
NSMutableDictionary *blockedSelectors = [objc_getAssociatedObject(self, &XJYThrottle) mutableCopy];
if (!blockedSelectors) {
blockedSelectors = [NSMutableDictionary dictionary];
objc_setAssociatedObject(self, &XJYThrottle, blockedSelectors, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
NSString *selectorName = NSStringFromSelector(aSelector);
if (![blockedSelectors objectForKey:selectorName]) {
[blockedSelectors setObject:selectorName forKey:selectorName];
objc_setAssociatedObject(self, &XJYThrottle, blockedSelectors, OBJC_ASSOCIATION_COPY_NONATOMIC);
dispatch_async(dispatch_get_main_queue(), ^{
vk_targetCallSelectorWithArgumentError(self, aSelector, boxingArguments, error);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(inteval * NSEC_PER_SEC)), [self getSerialQueue], ^{
[self xjy_unlockSelector:selectorName];
});
});
}
});
}
#pragma mark -
- (void)xjy_unlockSelector:(NSString *)selectorName
{
dispatch_async([self getSerialQueue], ^{
NSMutableDictionary *blockedSelectors = [objc_getAssociatedObject(self, &XJYThrottle) mutableCopy];
if ([blockedSelectors objectForKey:selectorName]) {
[blockedSelectors removeObjectForKey:selectorName];
}
objc_setAssociatedObject(self, &XJYThrottle, blockedSelectors, OBJC_ASSOCIATION_COPY_NONATOMIC);
});
}
- (dispatch_queue_t)getSerialQueue
{
dispatch_queue_t serialQueur = objc_getAssociatedObject(self, &XJYThrottleQueue);
if (!serialQueur) {
serialQueur = dispatch_queue_create("com.satanwoo.throttle", NULL);
objc_setAssociatedObject(self, &XJYThrottleQueue, serialQueur, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return serialQueur;
}
@end