TDSThrottle.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. //
  2. // TDSThrottle.h
  3. // TDSCommon
  4. //
  5. // Created by JiangJiahao on 2021/3/22.
  6. //
  7. #import <Foundation/Foundation.h>
  8. /** 自定管理执行与释放时,标记调用来源: 对象/类地址_方法名_调用行数 */
  9. #define TDSThrottleKey [NSString stringWithFormat:@"%p_%s_%d",self,__func__,__LINE__]
  10. #define TDSThrottleKeyAppendCustom(customKey) [NSString stringWithFormat:@"%p_%s_%d%@",self,__func__,__LINE__,customKey]
  11. NS_ASSUME_NONNULL_BEGIN
  12. typedef void(^TDSThrottleTaskBlock)(void);
  13. extern double const THROTTLE_INTERVAL; // 默认频率间隔, 0.5s
  14. /**
  15. 相邻调用必须间隔超时时间以上才会触发
  16. */
  17. @interface TDSThrottle : NSObject
  18. #pragma mark - 自动管理
  19. + (TDSThrottle *)throttleWithThrottleKey:(NSString *)throttleKey taskBlock:(TDSThrottleTaskBlock)taskBlock;
  20. + (TDSThrottle *)throttleWithInterval:(NSTimeInterval)interval
  21. throttleKey:(NSString *)throttleKey
  22. taskBlock:(TDSThrottleTaskBlock)taskBlock;
  23. /// 自动执行一个Throttle(节流)任务。
  24. /// 注意:适用调用不是异常频繁的任务,如用户按钮频繁点击限制
  25. /// @param interval 防抖间隔,默认0.5s
  26. /// @param queue 任务执行队列,默认主队列
  27. /// @param throttleKey 任务来源标识,可使用默认宏 TDSThrottleKey 或 TDSThrottleKeyAppendCustom
  28. /// @param taskBlock 需要执行的任务
  29. + (TDSThrottle *)throttleWithInterval:(NSTimeInterval)interval
  30. onQueue:(dispatch_queue_t)queue
  31. throttleKey:(NSString *)throttleKey
  32. taskBlock:(TDSThrottleTaskBlock)taskBlock;
  33. #pragma mark - 手动管理
  34. + (TDSThrottle *)manualThrottleWithTaskBlock:(TDSThrottleTaskBlock)taskBlock;
  35. + (TDSThrottle *)manualThrottleWithInterval:(NSTimeInterval)interval
  36. taskBlock:(TDSThrottleTaskBlock)taskBlock;
  37. /// 手动获取一个Throttle(节流)任务,需要在不再使用时手动调用 dispose 释放
  38. /// 注意:适合在任务会异常频繁执行时进行限制,如滑动列表时在频繁系统回调中处理的任务
  39. /// @param interval 抖间隔,默认0.5s
  40. /// @param queue 任务执行队列,默认主队列
  41. /// @param taskBlock 需要执行的任务
  42. + (TDSThrottle *)manualThrottleWithInterval:(NSTimeInterval)interval
  43. onQueue:(dispatch_queue_t)queue
  44. taskBlock:(TDSThrottleTaskBlock)taskBlock;
  45. #pragma mark - 执行与销毁
  46. /// 触发任务执行,手动管理时调用
  47. - (void)invoke;
  48. /// 销毁任务,手动管理时调用
  49. - (void)dispose;
  50. @end
  51. #pragma mark - private classes
  52. /**
  53. 调用后立即触发,间隔时间未超时无法再次触发,每次调用不会重新计时
  54. */
  55. @interface TDSThrottleLeading : TDSThrottle
  56. @end
  57. /**
  58. 调用后等待间隔时间超时以后触发,每次调用不会重新计时
  59. */
  60. @interface TDSThrottleTrailing : TDSThrottle
  61. @end
  62. /**
  63. 使用方法:
  64. 1.自动管理(自动执行/释放)
  65. // 按钮事件或需要执行的函数,任务使用 Throttle 包裹
  66. - (void)testThrottle {
  67. [TDSThrottleLeading throttleWithInterval:0.8 throttleKey:TDSThrottleKey taskBlock:^{
  68. // TODO 想要执行的任务
  69. }];
  70. }
  71. 2.手动管理 (创建时调用 manual 开头函数)
  72. @property (nonatomic, strong) TDSThrottle *testThrottler;
  73. // 按钮事件或需要执行的函数,任务使用 Throttle 包裹
  74. - (void)testThrottle {
  75. if (!self.testThrottler) {
  76. self.testThrottler = [TDSThrottleLeading manualThrottleWithTaskBlock:^{
  77. // TODO 想要执行的任务
  78. }];
  79. }
  80. [self.testThrottler invoke];
  81. }
  82. // 在适当时机,如退出页面时释放
  83. [self.testThrottler dispose];
  84. */
  85. NS_ASSUME_NONNULL_END