Code Monkey home page Code Monkey logo

blockhook's Introduction

BlockHook

Platform CI Status Version Carthage compatible codecov Codacy Badge GitHub release Twitter Follow

BlockHook

Hook Objective-C blocks with libffi. It's a powerful AOP tool for blocks. BlockHook can run your code before/instead/after invoking a block. BlockHook can even notify you when a block dealloc. You can trace the whole lifecycle of a block using BlockHook!

๐Ÿ“š Article

๐ŸŒŸ Features

  • Easy to use. Keep your code clear.
  • Support 4 hook modes: Before, Instead, After and Dead.
  • Let you modify return value and arguments.
  • Support invoking original implementation.
  • Reserve the whole arguments.
  • Self-managed tokens.
  • Support custom struct.
  • Support Carthage & CocoaPods.

๐Ÿ”ฎ Example

BlockHook needs libffi, which supports iOS and macOS. You can run BlockHookSample iOS or BlockHookSample macOS target.

๐Ÿ’ How to use

You can hook a block using 4 modes (before/instead/after/dead). This method returns a BHToken instance for more control. You can remove a BHToken, or set custom return value to its retValue property. Calling invokeOriginalBlock method will invoke original implementation of the block.

- (BHToken *)block_hookWithMode:(BlockHookMode)mode
                     usingBlock:(id)block

BlockHook is easy to use. Its APIs take example by Aspects. Here is a full set of usage of BlockHook.

NSObject *z = NSObject.new;
int (^block)(int, int) = ^(int x, int y) {
   int result = x + y;
   NSLog(@"%d + %d = %d, z is a NSObject: %p", x, y, result, z);
   return result;
};
    
    
BHToken *tokenInstead = [block block_hookWithMode:BlockHookModeInstead usingBlock:^(BHToken *token, int x, int y){
   [token invokeOriginalBlock];
   NSLog(@"let me see original result: %d", *(int *)(token.retValue));
   // change the block imp and result
   *(int *)(token.retValue) = x * y;
   NSLog(@"hook instead: '+' -> '*'");
}];

BHToken *tokenAfter = [block block_hookWithMode:BlockHookModeAfter usingBlock:^(BHToken *token, int x, int y){
   // print args and result
   NSLog(@"hook after block! %d * %d = %d", x, y, *(int *)(token.retValue));
}];

BHToken *tokenBefore = [block block_hookWithMode:BlockHookModeBefore usingBlock:^(id token){
   // BHToken has to be the first arg.
   NSLog(@"hook before block! token:%@", token);
}];
    
BHToken *tokenDead = [block block_hookWithMode:BlockHookModeDead usingBlock:^(id token){
   // BHToken is the only arg.
   NSLog(@"block dead! token:%@", token);
}];
    
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
   NSLog(@"hooked block");
   int ret = block(3, 5);
   NSLog(@"hooked result:%d", ret);
   // remove all tokens when you don't need.
   // reversed order of hook.
   [tokenBefore remove];
   [tokenAfter remove];
   [tokenInstead remove];
   NSLog(@"remove tokens, original block");
   ret = block(3, 5);
   NSLog(@"original result:%d", ret);
//        [tokenDead remove];
});

Here is the log:

hooked block
hook before block! token:<BHToken: 0x1d00f0d80>
3 + 5 = 8, z is a NSObject: 0x1d00172b0
let me see original result: 8
hook instead: '+' -> '*'
hook after block! 3 * 5 = 15
hooked result:15
remove tokens, original block
3 + 5 = 8, z is a NSObject: 0x1d00172b0
original result:8
block dead! token:<BHToken: 0x1d00f9900>

๐Ÿ“ฒ Installation

CocoaPods

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

$ gem install cocoapods

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

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
target 'MyApp' do
	pod 'BlockHook'
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 BlockHook into your Xcode project using Carthage, specify it in your Cartfile:

github "yulingtianxia/BlockHook"

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

Manual

After importing libffi, just add the two files BlockHook.h/m to 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

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

Thanks to MABlockClosure and Aspects!

blockhook's People

Contributors

codacy-badger avatar yulingtianxia avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.