• Stars
    star
    823
  • Rank 55,011 (Top 2 %)
  • Language
    Objective-C
  • License
    MIT License
  • Created almost 7 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A lightweight Objective-C message throttle and debounce library.

MessageThrottle

CI Status Version Carthage compatible codecov Codacy Badge License Platform CocoaPods CocoaPods Twitter Follow

MessageThrottle

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. For a visual explaination of the differences between throttling and debouncing, see this demo.

📚 Article

🌟 Features

  • Easy to use.
  • Keep your code clear
  • Reserve the whole arguments.
  • Support instance, class and meta class.
  • Support 3 modes: Throttle(Firstly), Throttle(Last) and Debounce.
  • Centralized management of rules.
  • Self-managed rules.
  • Let method MUST invoke at the specified conditions.
  • Persistent rules.

🔮 Example

To run the example project, clone the repo and run MTDemo target.

🐒 How to use

The following example shows how to restrict the frequency of forwarding - [ViewController foo:] message to 100 times per second.

Stub *s = [Stub new];
MTRule *rule = [s limitSelector:@selector(foo:) oncePerDuration:0.01]; // returns MTRule instance

For more control of rule, you can use mt_limitSelector:oncePerDuration:usingMode:onMessageQueue:alwaysInvokeBlock:.

You can also start with a creation of MTRule:

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 apply];

You can let method MUST invoke at the specified conditions using alwaysInvokeBlock. The example code above will invoke message immediately if its 1st parameter equals "1970". BTW, alwaysInvokeBlock can has no parameter, or has one more MTRule before message's parameter list.

You should call discard method When you don't need limit foo: method.

[rule discard];

NOTE: MTRule is self-managed. If the target of rule is a object instance, MTRule will discard itself automatically when the target is deallocated.

Some rules may have large durationThreshold. You can set property persistent to YES, and save them on disk by calling savePersistentRules method. These persistent rules will be applied after MTEngine class is loaded. savePersistentRules will be called automatically when receive terminate notification.

rule.persistent = YES;
[MTEngine.defaultEngine savePersistentRules];

MTRule represents the rule of a message throttle, which contains strategy and frequency of sending messages.

You can assign an instance or (meta)class to target property. When you assign an instance to target, MessageThrottle will only restrict messages send to this instance. If you want to restrict a class method, just using mt_metaClass() to get it's meta class, and assign the meta class to target. Rules with instance target won't conflict with each other, and have a higher priority than rules with class target.

NOTE: A message can only have one rule per class hierarchy. For example, If there is one rule of message - [Stub foo:], you can't add another rule of message - [SuperStub foo:] anymore. PS: Assume that Stub is a subclass of SuperStub.

MTRule also define the mode of performing selector. There are three modes defined in MTMode: MTModePerformFirstly, MTModePerformLast and MTModePerformDebounce. This demo shows the difference between throttle and debounce.

The default mode is MTModePerformDebounce. MTModePerformDebounce will restart timer when another message arrives during durationThreshold. So there must be a delay of durationThreshold at least.

MTModePerformDebounce:
start                                        end
|           durationThreshold(old)             |
@----------------------@---------------------->>
|                      |                 
ignore                 will perform at end of new duration
                       |--------------------------------------------->>
                       |           durationThreshold(new)             |
                       start                                        end

MTModePerformFirstly will performs the first message and ignore all following messages during durationThreshold.

MTModePerformFirstly:
start                                                                end
|                           durationThreshold                          |
@-------------------------@----------@---------------@---------------->>
|                         |          |               |          
perform immediately       ignore     ignore          ignore     

MTModePerformLast performs the last message at end time. Please note that does not perform message immediately, the delay could be durationThreshold at most.

MTModePerformLast:
start                                                                end
|                           durationThreshold                          |
@-------------------------@----------@---------------@---------------->>
|                         |          |               |          
ignore                    ignore     ignore          will perform at end

When using MTModePerformLast or MTModePerformDebounce, you can designate a dispatch queue which messages perform on. The messageQueue is main queue by default. MTModePerformLast and MTModePerformDebounce modes will also use the last arguments to perform messages.

MTEngine is a singleton class. It manages all rules of message throttles. You can use applyRule: method to apply a rule or update an old rule that already exists. Using it's discardRule: method to discardRule a rule. There is also a readonly property allRules for obtaining all rules in current application.

📲 Installation

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:

$ gem install cocoapods

To integrate MessageThrottle into your Xcode project using CocoaPods, specify it in your Podfile:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '11.0'
use_frameworks!
target 'MyApp' do
	pod 'MessageThrottle'
end

You need replace "MyApp" with your project's name.

Then, run the following command:

$ pod install

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.

You can install Carthage with Homebrew using the following command:

$ brew update
$ brew install carthage

To integrate MessageThrottle into your Xcode project using Carthage, specify it in your Cartfile:

github "yulingtianxia/MessageThrottle"

Run carthage update to build the framework and drag the built MessageThrottleKit.framework into your Xcode project.

Manual

Just drag the "MessageThrottle" document folder into your project.

❤️ Contributed

  • If you need help or you'd like to ask a general question, open an issue.
  • If you found a bug, open an issue.
  • If you have a feature request, open an issue.
  • If you want to contribute, submit a pull request.

👨🏻‍💻 Author

yulingtianxia, [email protected]

👮🏻 License

MessageThrottle is available under the MIT license. See the LICENSE file for more info.

More Repositories

1

FishChat

Hook WeChat.app on non-jailbroken devices.
1,118
star
2

TBActionSheet

A Custom&Powerful Action Sheet For iOS. 一个 ActionSheet 满足所有样式!超高自由度的可定制!
Objective-C
950
star
3

BlockHook

Hook Objective-C blocks. A powerful AOP tool.
C
836
star
4

AppOrderFiles

The easiest way to generate order files for Mach-O using Clang. Improving App Performance.
Objective-C
652
star
5

pbxprojHelper

A macOS tool help you handling project.pbxproj files. Written in Swift 5!
Swift
484
star
6

TBUIAutoTest

Generating UI test label automatically for iOS.
Objective-C
349
star
7

FuckFakeGitHubStars

GitHub 虚假 Star 净网行动
Python
265
star
8

Core-ML-Sample

A Demo using Vision Framework building on Core ML Framework
Swift
218
star
9

YXYDashLayer

Colorful Rounded Rect Dash Border
Objective-C
175
star
10

SimilarImageHunter

Mac 上寻找相似内容的图片工具
Objective-C
172
star
11

HardChoice

有时候作抉择真的很痛苦,Swift写的生活类APP
Swift
92
star
12

Spiral

A Game Developed with Swift and SpriteKit
Swift
88
star
13

AudioEmotion

Recognize Audio Emotion.
Python
86
star
14

BlockTracker

Tracking block args of Objective-C method based on BlockHook
Objective-C
78
star
15

PhotoAssessment

Photo Assessment using Core ML and Metal.
Objective-C
72
star
16

ColorAtom

用SpriteKit写的关于正能量的小游戏
Objective-C
49
star
17

Algorithm-Experiment

Algorithm experiment code written by Swift
Swift
46
star
18

Self-Sizing-CollectionView-Demo

This is the Demo showed in http://yulingtianxia.com/blog/2014/08/17/New-in-Table-and-Collection-Views/
Swift
35
star
19

YXYNumberAnimationLabel

一个数字动画Label
Objective-C
33
star
20

TFSHelper

Mac 上自动捕获并打开 TFS 链接的小工具
Swift
32
star
21

WebViewImageClick

看美图必备
Objective-C
27
star
22

ClassWrittenInSwift

Something for Class written in Swift.
Objective-C++
18
star
23

ImageMask

iOS刮刮卡的实现
Objective-C
17
star
24

javaQQ

用java写的QQ客户端,简单地聊天和发送文件功能
Java
14
star
25

DirtyWords-for-Xcode

Highlight dirty words in Xcode.
Swift
11
star
26

HandGestureCNN

Trainning Inception v3 model with Keras, and predict with MPS on iOS.
Swift
10
star
27

ChangYou

畅游室内导航
Java
7
star
28

Blog-Hexo-Source

My Blog Source
JavaScript
5
star
29

yulingtianxia.github.io

我的技术博客
HTML
5
star
30

MyCDDemo

Core Data Demo
Objective-C
4
star
31

Linger

临哥让我做的内部使用的 Mac 平台简易日志分析工具,不知道起啥名字好,就叫 Linger 吧
Objective-C
3
star
32

Pebble-MoHa

Pebble Watchface +1s
C
2
star
33

FavoriteGirls

Machine Learning Demo
Python
2
star
34

MyFirstGame

无聊写的小游戏
Objective-C
1
star
35

LeetCode

记录LeetCode刷题
C++
1
star