
Libffi를 사용한 Hook Objective-C 블록. 블록을위한 강력한 AOP 도구입니다. Blockhook은 블록을 호출 한 후/대신/대신 코드를 실행할 수 있습니다. Blockhook은 블록 거래일 때 알려줄 수도 있습니다. Blockhook을 사용하여 블록의 전체 수명주기를 추적 할 수 있습니다!
방법에 전달되는 블록을 연결하고 싶습니까? BlockTracker를 사용해보십시오!
Blockhook은 iOS, TVOS 및 MacOS를 지원하는 Libffi가 필요합니다. BlockHookSample iOS , BlockHookSample tvOS 또는 BlockHookSample macOS 대상을 실행할 수 있습니다.
4 개의 모드 (이전/대체/후/죽음)를 사용하여 블록을 연결할 수 있습니다. 이 메소드는 더 많은 제어를 위해 BHToken 인스턴스를 반환합니다. BHToken remove 하거나 사용자 지정 반환 값을 retValue 속성으로 설정할 수 있습니다. invokeOriginalBlock 메소드를 호출하면 블록의 원래 구현이 호출됩니다.
- (BHToken *)block_hookWithMode:(BlockHookMode)mode
usingBlock:( id )blockBlockhook은 사용하기 쉽습니다. API는 측면별로 예제를 취합니다. 다음은 Blockhook의 전체 사용 세트입니다.
이것은 모든 모드에서 블록을 고치기위한 예입니다. 블록 반환 값을 8에서 15로 변경할 수 있습니다. 그런 다음 약간의 후크를 제거하고 성공했는지 확인하십시오. 마지막으로 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 installCarthage는 종속성을 구축하고 이진 프레임 워크를 제공하는 분산 형 종속 관리자입니다.
다음 명령을 사용하여 Homebrew로 Carthage를 설치할 수 있습니다.
$ brew update
$ brew install carthage Carthage를 사용하여 Blockhook을 Xcode 프로젝트에 통합하려면 Cartfile 에 지정하십시오.
github "yulingtianxia/BlockHook"
carthage update 실행하여 프레임 워크를 구축하고 Built BlockHook.framework 를 Xcode 프로젝트로 드래그하십시오.
libffi를 가져 오면 프로젝트에 두 파일 BlockHook.h/m 추가하십시오.
Yulingtianxia, [email protected]
Blockhook은 MIT 라이센스에 따라 제공됩니다. 자세한 내용은 라이센스 파일을 참조하십시오.
Mablockclosure와 측면 덕분에!