From 7f129e08cb3741e770acf965e6f8b46b28459a26 Mon Sep 17 00:00:00 2001 From: yulingtianxia Date: Sun, 2 Jun 2019 15:48:54 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=B3=BB=E7=BB=9F=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E6=A0=A1=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 提供接口校正用户修改系统时间作弊 2. MTRule 部分属性改为只读,减少线程安全风险 --- MTDemo/MTDemoTests/MTDemoTests.m | 5 ++--- MessageThrottle.podspec | 2 +- MessageThrottle/MessageThrottle.h | 18 ++++++++++++++---- MessageThrottle/MessageThrottle.m | 8 +++++--- README.md | 7 ------- 5 files changed, 22 insertions(+), 18 deletions(-) diff --git a/MTDemo/MTDemoTests/MTDemoTests.m b/MTDemo/MTDemoTests/MTDemoTests.m index 810f1bd..c982167 100644 --- a/MTDemo/MTDemoTests/MTDemoTests.m +++ b/MTDemo/MTDemoTests/MTDemoTests.m @@ -289,10 +289,9 @@ - (void)testApplyRuleTwice { - (void)testPerformanceExample { // This is an example of a performance test case. - MTRule *rule = [self.stub mt_limitSelector:@selector(foo:) oncePerDuration:0.01 usingMode:MTPerformModeDebounce]; - rule.alwaysInvokeBlock = ^(MTRule *rule, NSDate *date) { + [self.stub mt_limitSelector:@selector(foo:) oncePerDuration:0.01 usingMode:MTPerformModeDebounce onMessageQueue:nil alwaysInvokeBlock:^(MTRule *rule, NSDate *date) { return YES; - }; + }]; NSDate *date = [NSDate date]; [self measureBlock:^{ // Put the code you want to measure the time of here. diff --git a/MessageThrottle.podspec b/MessageThrottle.podspec index 52c2642..d0c358f 100644 --- a/MessageThrottle.podspec +++ b/MessageThrottle.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "MessageThrottle" -s.version = "1.3.6" +s.version = "1.3.7" s.summary = "A lightweight Objective-C message throttle and debounce library." s.description = <<-DESC MessageThrottle is a lightweight, simple library for controlling frequency of forwarding Objective-C messages. You can choose to control existing methods per instance or per class. It's an implementation of function throttle/debounce developed with Objective-C runtime. diff --git a/MessageThrottle/MessageThrottle.h b/MessageThrottle/MessageThrottle.h index e0b6fea..74e144c 100644 --- a/MessageThrottle/MessageThrottle.h +++ b/MessageThrottle/MessageThrottle.h @@ -61,12 +61,12 @@ Class mt_metaClass(Class cls); block 传入的第一个参数为 `self`,其余参数列表与消息调用的参数列表相同。 block 如果返回 YES,则消息立即执行,但不会影响当前节流模式。 */ -@property (nonatomic) id alwaysInvokeBlock; +@property (nonatomic, readonly) id alwaysInvokeBlock; /** MTModePerformLastly 和 MTModePerformDebounce 模式下消息发送的队列,默认在主队列 */ -@property (nonatomic) dispatch_queue_t messageQueue; +@property (nonatomic, readonly) dispatch_queue_t messageQueue; /** 是否持久化规则。如果选择持久化,下次启动 App 将会自动应用规则;默认为 NO,规则只在内存中生效。 @@ -102,8 +102,18 @@ Class mt_metaClass(Class cls); @interface MTEngine : NSObject @property (nonatomic, class, readonly) MTEngine *defaultEngine; + +/** + 获取所有规则 + */ @property (nonatomic, readonly) NSArray *allRules; +/** + 校正系统时间所需的差值。用户可能手动修改系统时间,此时可以计算服务器时间与系统时间的差值进行修正。 + 单位:秒 + */ +@property (nonatomic) NSTimeInterval correctionForSystemTime; + /** 应用规则,会覆盖已有的规则 @@ -166,7 +176,7 @@ Class mt_metaClass(Class cls); @param messageQueue 延时执行方法的队列 @return 如果限频成功则返回规则对象,否则返回 nil */ -- (nullable MTRule *)mt_limitSelector:(SEL)selector oncePerDuration:(NSTimeInterval)durationThreshold usingMode:(MTPerformMode)mode onMessageQueue:(dispatch_queue_t)messageQueue; +- (nullable MTRule *)mt_limitSelector:(SEL)selector oncePerDuration:(NSTimeInterval)durationThreshold usingMode:(MTPerformMode)mode onMessageQueue:(nullable dispatch_queue_t)messageQueue; /** 对方法调用限频,可以指定方法某种情况下一定会调用。 @@ -179,7 +189,7 @@ Class mt_metaClass(Class cls); @param alwaysInvokeBlock 是否必须执行消息。block 的参数列表可选,返回值为 BOOL 类型。参考 `MTRule`。 @return 如果限频成功则返回规则对象,否则返回 nil */ -- (nullable MTRule *)mt_limitSelector:(SEL)selector oncePerDuration:(NSTimeInterval)durationThreshold usingMode:(MTPerformMode)mode onMessageQueue:(dispatch_queue_t)messageQueue alwaysInvokeBlock:(nullable id)alwaysInvokeBlock; +- (nullable MTRule *)mt_limitSelector:(SEL)selector oncePerDuration:(NSTimeInterval)durationThreshold usingMode:(MTPerformMode)mode onMessageQueue:(nullable dispatch_queue_t)messageQueue alwaysInvokeBlock:(nullable id)alwaysInvokeBlock; @end diff --git a/MessageThrottle/MessageThrottle.m b/MessageThrottle/MessageThrottle.m index 48be400..f31e189 100644 --- a/MessageThrottle/MessageThrottle.m +++ b/MessageThrottle/MessageThrottle.m @@ -127,6 +127,8 @@ @interface MTRule () @property (nonatomic) NSInvocation *lastInvocation; @property (nonatomic) SEL aliasSelector; @property (nonatomic, readwrite, getter=isActive) BOOL active; +@property (nonatomic, readwrite) id alwaysInvokeBlock; +@property (nonatomic, readwrite) dispatch_queue_t messageQueue; @end @@ -363,7 +365,6 @@ - (void)savePersistentRules return [rules copy]; } - /** 添加 target-selector 记录 @@ -515,7 +516,7 @@ - (void)discardRule:(MTRule *)rule whenTargetDealloc:(MTDealloc *)mtDealloc pthread_mutex_unlock(&mutex); } -#pragma mark - Private Helper +#pragma mark - Private Helper Function static BOOL mt_checkRuleValid(MTRule *rule) { @@ -600,6 +601,7 @@ static void mt_handleInvocation(NSInvocation *invocation, MTRule *rule) } NSTimeInterval now = [[NSDate date] timeIntervalSince1970]; + now += MTEngine.defaultEngine.correctionForSystemTime; switch (rule.mode) { case MTPerformModeFirstly: { @@ -937,7 +939,7 @@ - (nullable MTRule *)mt_limitSelector:(SEL)selector oncePerDuration:(NSTimeInter } rule.durationThreshold = durationThreshold; rule.mode = mode; - rule.messageQueue = messageQueue; + rule.messageQueue = messageQueue ?: dispatch_get_main_queue(); rule.alwaysInvokeBlock = alwaysInvokeBlock; rule.persistent = (mode == MTPerformModeFirstly && durationThreshold > 5 && mt_object_isClass(self)); if (isNewRule) { diff --git a/README.md b/README.md index d452995..0a71c22 100644 --- a/README.md +++ b/README.md @@ -62,13 +62,6 @@ Stub *s = [Stub new]; // You can also assign `Stub.class` or `mt_metaClass(Stub.class)` to `target` argument. MTRule *rule = [[MTRule alloc] initWithTarget:s selector:@selector(foo:) durationThreshold:0.01]; rule.mode = MTModePerformLast; // Or `MTModePerformFirstly`, ect -rule.messageQueue = /** a dispatch queue you want, maybe `dispatch_get_main_queue()` whatever...*/ -rule.alwaysInvokeBlock = ^(MTRule *rule, NSDate *date) { - if ([date isEqualToDate:[NSDate dateWithTimeIntervalSince1970:0]]) { - return YES; - } - return NO; -}; [rule apply]; ```