
Hook Objective-C Blok dengan libffi. Ini adalah alat AOP yang kuat untuk blok. Blockhook dapat menjalankan kode Anda sebelum/sebagai gantinya/setelah memohon blok. Blockhook bahkan dapat memberi tahu Anda saat blok Dealloc. Anda dapat melacak seluruh siklus hidup blok menggunakan Blockhook!
Ingin mengaitkan blok yang lewat ke metode? Coba Blocktracker!
Blockhook membutuhkan libffi, yang mendukung iOS, TVOS, dan macOS. Anda dapat menjalankan BlockHookSample iOS , BlockHookSample tvOS atau BlockHookSample macOS target.
Anda dapat mengaitkan blok menggunakan 4 mode (sebelum/sebagai gantinya/sesudah/mati). Metode ini mengembalikan instance BHToken untuk kontrol lebih lanjut. Anda dapat remove BHToken , atau menetapkan nilai pengembalian khusus ke properti retValue -nya. Memanggil metode invokeOriginalBlock akan memohon implementasi asli blok.
- (BHToken *)block_hookWithMode:(BlockHookMode)mode
usingBlock:( id )blockBlockhook mudah digunakan. API -nya mengambil contoh berdasarkan aspek. Berikut ini adalah satu set lengkap penggunaan blockhook.
Ini adalah contoh untuk blok pengait di semua mode. Anda dapat mengubah nilai pengembalian blok dari 8 ke 15. Kemudian lepaskan beberapa kait dan periksa apakah itu berhasil. Akhirnya kami mendapat panggilan balik saat 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);Ini log:
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
Terkadang Anda ingin login pengguna terlebih dahulu sebelum rute ke komponen lain. Untuk mencegat blok tanpa meretas kode router, Anda dapat menggunakan Block Interceptor.
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 adalah manajer ketergantungan untuk proyek kakao. Anda dapat menginstalnya dengan perintah berikut:
$ gem install cocoapods Untuk mengintegrasikan blockhook ke dalam proyek XCODE Anda menggunakan Cocoapods, tentukan di Podfile Anda:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
target 'MyApp' do
pod 'BlockHook'
end
Anda perlu mengganti "myapp" dengan nama proyek Anda.
Kemudian, jalankan perintah berikut:
$ pod installCarthage adalah manajer ketergantungan terdesentralisasi yang membangun ketergantungan Anda dan memberi Anda kerangka kerja biner.
Anda dapat menginstal carthage dengan homebrew menggunakan perintah berikut:
$ brew update
$ brew install carthage Untuk mengintegrasikan blockhook ke dalam proyek XCode Anda menggunakan Carthage, tentukan di Cartfile Anda:
github "yulingtianxia/BlockHook"
Jalankan carthage update untuk membangun kerangka kerja dan seret BlockHook.framework yang dibangun ke dalam proyek XCODE Anda.
Setelah mengimpor libffi, cukup tambahkan dua file BlockHook.h/m ke proyek Anda.
yulingtianxia, [email protected]
Blockhook tersedia di bawah lisensi MIT. Lihat file lisensi untuk info lebih lanjut.
Terima kasih kepada Mablockclosure and Aspects!