
Haken-Objektive-C-Blöcke mit libffi. Es ist ein leistungsstarkes AOP -Tool für Blöcke. Blockhook kann Ihren Code vor/stattdessen/nach dem Aufrufen eines Blocks ausführen. BlockHook kann Sie sogar benachrichtigen, wenn ein Block Dealloc. Sie können den gesamten Lebenszyklus eines Blocks mit Blockhook verfolgen!
Möchten Sie Blöcke an Methoden anschließen? Probieren Sie Blocktracker!
Blockhook braucht libffi, das iOS, tvos und macos unterstützt. Sie können BlockHookSample iOS , BlockHookSample tvOS oder BlockHookSample macOS -Ziel ausführen.
Sie können einen Block mit 4 Modi anschließen (vor/stattdessen/nach/toT). Diese Methode gibt eine BHToken -Instanz für mehr Kontrolle zurück. Sie können einen BHToken remove oder den benutzerdefinierten Rückgabewert auf seine retValue -Eigenschaft festlegen. Calling invokeOriginalBlock -Methode ruft die ursprüngliche Implementierung des Blocks auf.
- (BHToken *)block_hookWithMode:(BlockHookMode)mode
usingBlock:( id )blockBlockhook ist einfach zu bedienen. Seine APIs nehmen ein Beispiel nach Aspekten. Hier ist eine vollständige Verwendung von Blockhook.
Dies ist ein Beispiel für das Hooking -Block in allen Modi. Sie können den Blockrückgabewert von 8 auf 15 ändern. Dann entfernen Sie einen Haken und prüfen, ob er erfolgreich ist. Schließlich erhalten wir einen Rückruf, wenn Block Overlyloc.
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);Hier ist das Protokoll:
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
Manchmal möchten Sie sich zuerst anmelden, bevor Benutzer an andere Komponenten weitergeleitet werden. Um einen Block abzufangen, ohne in den Code von Routern zu hacken, können Sie Block Interceptor verwenden.
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 ist ein Abhängigkeitsmanager für Kakaoprojekte. Sie können es mit dem folgenden Befehl installieren:
$ gem install cocoapods Um Blockhook mit Cocoapods in Ihr Xcode -Projekt zu integrieren, geben Sie es in Ihrer Podfile an:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
target 'MyApp' do
pod 'BlockHook'
end
Sie müssen "MyApp" durch den Namen Ihres Projekts ersetzen.
Führen Sie dann den folgenden Befehl aus:
$ pod installKarthago ist ein dezentraler Abhängigkeitsmanager, der Ihre Abhängigkeiten erstellt und Ihnen binäre Rahmenbedingungen bietet.
Sie können Carthago mit Homebrew mit dem folgenden Befehl installieren:
$ brew update
$ brew install carthage Um Blockhook mit Karthago in Ihr Xcode -Projekt zu integrieren, geben Sie es in Ihrem Cartfile an:
github "yulingtianxia/BlockHook"
Führen Sie carthage update aus, um das Framework zu erstellen und den bauten BlockHook.framework in Ihr Xcode -Projekt zu ziehen.
Fügen Sie nach dem Importieren von Libffi einfach die beiden Dateien BlockHook.h/m zu Ihrem Projekt hinzu.
yulingtianxia, [email protected]
Blockhook ist unter der MIT -Lizenz erhältlich. Weitere Informationen finden Sie in der Lizenzdatei.
Vielen Dank an MablockClosure und Aspekte!