
Bloques de Objetivo-C de gancho con libffi. Es una poderosa herramienta AOP para bloques. Blockhook puede ejecutar su código antes/en su lugar/después de invocar un bloque. Blockhook puede incluso notificarle cuándo un trastloc de block. ¡Puede rastrear todo el ciclo de vida de un bloque usando blockhook!
¿Quiere que los bloques de gancho pasen a los métodos? ¡Prueba blocktracker!
Blockhook necesita libffi, que admite iOS, TVOS y macOS. Puede ejecutar BlockHookSample iOS , BlockHookSample tvOS o BlockHookSample macOS Target.
Puede enganchar un bloque con 4 modos (antes/en su lugar/después/muerto). Este método devuelve una instancia BHToken para obtener más control. Puede remove un BHToken o establecer el valor de retorno personalizado en su propiedad retValue . Llamar al método invokeOriginalBlock invocará la implementación original del bloque.
- (BHToken *)block_hookWithMode:(BlockHookMode)mode
usingBlock:( id )blockBlockhook es fácil de usar. Sus API toman ejemplo por aspectos. Aquí hay un conjunto completo de uso de Blockhook.
Este es un ejemplo para el bloque de enganche en todos los modos. Puede cambiar el valor de retorno de bloque de 8 a 15. Luego, retire un poco de gancho y verifique si es exitoso. Finalmente recibimos devolución de llamada cuando 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);Aquí está el registro:
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
A veces desea iniciar sesión de usuario primero antes de enrutar a otros componentes. Para interceptar un bloque sin piratear el código de enrutadores, puede usar el interceptor de bloques.
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 es un gerente de dependencia para proyectos de cacao. Puede instalarlo con el siguiente comando:
$ gem install cocoapods Para integrar blockhook en su proyecto Xcode con CocoAPods, especifíquelo en su Podfile :
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
target 'MyApp' do
pod 'BlockHook'
end
Necesita reemplazar "MyApp" con el nombre de su proyecto.
Luego, ejecute el siguiente comando:
$ pod installCarthage es un gerente de dependencia descentralizado que construye sus dependencias y le proporciona marcos binarios.
Puede instalar Carthage con HomeBrew usando el siguiente comando:
$ brew update
$ brew install carthage Para integrar blockhook en su proyecto Xcode utilizando Carthage, especifíquelo en su Cartfile :
github "yulingtianxia/BlockHook"
Ejecute carthage update para construir el marco y arrastre el BlockHook.framework construido en su proyecto Xcode.
Después de importar libffi, simplemente agregue los dos archivos BlockHook.h/m a su proyecto.
Yulingtianxia, [email protected]
Blockhook está disponible bajo la licencia MIT. Consulte el archivo de licencia para obtener más información.
¡Gracias a maBlockClase y aspectos!