
用libffi鉤上Objective-C塊。這是一個強大的AOP工具。 BlockHook可以在調用塊之前///////////nock thake之後運行您的代碼。 Blockhook甚至可以在Block DealLoc時通知您。您可以使用BlockHook追踪塊的整個生命週期!
想要鉤塊傳遞到方法嗎?嘗試BlockTracker!
BlockHook需要支持iOS,TVOS和MACOS的Libffi。您可以運行BlockHookSample iOS , BlockHookSample tvOS或BlockHookSample macOS目標。
您可以使用4個模式(代替/之後/死亡)鉤住一個塊。此方法返回一個BHToken實例以進行更多控制。您可以remove BHToken ,或將自定義返回值設置為其retValue屬性。調用invokeOriginalBlock方法將調用該塊的原始實現。
- (BHToken *)block_hookWithMode:(BlockHookMode)mode
usingBlock:( id )blockBlockhook易於使用。它的API以方面為例。這是塊狀的全套用法。
這是所有模式中鉤塊的示例。您可以將塊返回值從8更改為15。然後刪除一些掛鉤,然後檢查它是否成功。最後,當DealLoc Block DealLoc時,我們會得到回調。
NSObject *z = NSObject .new;
int (^block)( int x, int y) = ^ int ( int x, int y) {
int result = x + y;
NSLog ( @" %d + %d = %d , z is a NSObject: %@ " , x, y, result, z);
return result;
};
BHToken *token = [block block_hookWithMode: BlockHookModeDead|BlockHookModeBefore|BlockHookModeInstead|BlockHookModeAfter usingBlock: ^(BHInvocation *invocation, int x, int y) {
int ret = 0 ;
[invocation getReturnValue: &ret];
switch (invocation. mode ) {
case BlockHookModeBefore:
// BHInvocation has to be the first arg.
NSLog ( @" hook before block! invocation: %@ " , invocation);
break ;
case BlockHookModeInstead:
[invocation invokeOriginalBlock ];
NSLog ( @" let me see original result: %d " , ret);
// change the block imp and result
ret = x * y;
[invocation setReturnValue: &ret];
NSLog ( @" hook instead: '+' -> '*' " );
break ;
case BlockHookModeAfter:
// print args and result
NSLog ( @" hook after block! %d * %d = %d " , x, y, ret);
break ;
case BlockHookModeDead:
// BHInvocation is the only arg.
NSLog ( @" block dead! token: %@ " , invocation. token );
break ;
default :
break ;
}
}];
NSLog ( @" hooked block " );
int ret = block( 3 , 5 );
NSLog ( @" hooked result: %d " , ret);
// remove token.
[token remove ];
NSLog ( @" remove tokens, original block " );
ret = block( 3 , 5 );
NSLog ( @" original result: %d " , ret);這是日誌:
hooked block
hook before block! invocation:<BHInvocation: 0x60b00003c370>
3 + 5 = 8, z is a NSObject: <NSObject: 0x6020000279d0>
let me see original result: 0
hook instead: '+' -> '*'
hook after block! 3 * 5 = 15
hooked result:15
block dead! token:<BHToken: 0x60d000004bd0>
remove tokens, original block
3 + 5 = 8, z is a NSObject: <NSObject: 0x6020000279d0>
original result:8
有時,您需要先用戶登錄,然後再將其路由到其他組件。要攔截塊而無需黑客入侵路由器的代碼,您可以使用塊攔截器。
NSObject *testArg = [ NSObject new ];
NSObject *testArg1 = [ NSObject new ];
NSObject *(^testblock)( NSObject *) = ^( NSObject *a) {
return [ NSObject new ];
};
[testblock block_interceptor: ^(BHInvocation *invocation, IntercepterCompletion _Nonnull completion) {
dispatch_after ( dispatch_time (DISPATCH_TIME_NOW, ( int64_t )( 0.5 * NSEC_PER_SEC)), dispatch_get_main_queue (), ^{
NSObject * __unsafe_unretained arg;
[invocation getArgument: &arg atIndex: 1 ];
NSLog ( @" Original argument: %@ " , arg);
[invocation setArgument: ( void *)&testArg1 atIndex: 1 ];
completion ();
});
}];
testblock (testArg);Cocoapods是可可項目的依賴性經理。您可以使用以下命令安裝它:
$ gem install cocoapods要使用Cocoapods將Blockhook集成到您的Xcode項目中,請在您的Podfile中指定:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
target 'MyApp' do
pod 'BlockHook'
end
您需要用項目的名稱替換“ myApp”。
然後,運行以下命令:
$ pod install迦太基是一個分散的依賴管理器,可建立您的依賴關係並為您提供二進制框架。
您可以使用以下命令使用Homebrew安裝迦太基:
$ brew update
$ brew install carthage要使用迦太基將Blockhook集成到您的Xcode項目中,請在您的Cartfile中指定它:
github "yulingtianxia/BlockHook"
運行carthage update以構建框架並將已構建的BlockHook.framework拖到Xcode項目中。
導入libffi後,只需將兩個文件BlockHook.h/m添加到您的項目。
Yulingtianxia,[email protected]
Blockhook可根據MIT許可證獲得。有關更多信息,請參見許可證文件。
多虧了披露和方面!