
Hook Objective-C บล็อกด้วย libffi มันเป็นเครื่องมือ AOP ที่ทรงพลังสำหรับบล็อก Blockhook สามารถเรียกใช้รหัสของคุณก่อน/แทน/หลังจากเรียกใช้บล็อก Blockhook ยังสามารถแจ้งให้คุณทราบเมื่อมีการบล็อก dealloc คุณสามารถติดตามวงจรชีวิตทั้งหมดของบล็อกโดยใช้ Blockhook!
ต้องการขอบล็อกผ่านไปยังวิธีการหรือไม่? ลอง Blocktracker!
Blockhook ต้องการ Libffi ซึ่งรองรับ iOS, TVOS และ MacOS คุณสามารถเรียกใช้ BlockHookSample iOS , BlockHookSample tvOS หรือเป้าหมาย BlockHookSample macOS
คุณสามารถขอบล็อกโดยใช้ 4 โหมด (ก่อน/หลัง/หลัง/ตาย) วิธีนี้ส่งคืนอินสแตนซ์ BHToken สำหรับการควบคุมเพิ่มเติม คุณสามารถ remove BHToken หรือตั้งค่าการส่งคืนแบบกำหนดเองเป็นคุณสมบัติ retValue การเรียกใช้วิธีการของ invokeOriginalBlock จะเรียกใช้การใช้งานดั้งเดิมของบล็อก
- (BHToken *)block_hookWithMode:(BlockHookMode)mode
usingBlock:( id )blockBlockhook ใช้งานง่าย API ของมันเป็นตัวอย่างโดยด้าน นี่คือชุดการใช้งานเต็มรูปแบบของ blockhook
นี่คือตัวอย่างสำหรับการเชื่อมต่อบล็อกในทุกโหมด คุณสามารถเปลี่ยนค่าการส่งคืนบล็อกจาก 8 เป็น 15 จากนั้นลบตะขอบางส่วนและตรวจสอบว่าสำเร็จหรือไม่ ในที่สุดเราก็ได้รับการโทรกลับเมื่อบล็อก 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 ในการรวม blockhook เข้ากับโครงการ XCode ของคุณโดยใช้ cocoapods ให้ระบุใน Podfile ของคุณ:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
target 'MyApp' do
pod 'BlockHook'
end
คุณต้องแทนที่ "MyApp" ด้วยชื่อโครงการของคุณ
จากนั้นเรียกใช้คำสั่งต่อไปนี้:
$ pod installคาร์เธจเป็นตัวจัดการการพึ่งพากระจายอำนาจที่สร้างการพึ่งพาของคุณและให้กรอบไบนารีแก่คุณ
คุณสามารถติดตั้ง Carthage ด้วย Homebrew โดยใช้คำสั่งต่อไปนี้:
$ brew update
$ brew install carthage ในการรวม blockhook เข้ากับโครงการ XCode ของคุณโดยใช้ Carthage ให้ระบุใน Cartfile ของคุณ:
github "yulingtianxia/BlockHook"
เรียกใช้ carthage update เพื่อสร้างเฟรมเวิร์กและลาก BlockHook.framework ที่สร้างขึ้นในโครงการ XCode ของคุณ
หลังจากนำเข้า libffi เพียงเพิ่มสองไฟล์ BlockHook.h/m ลงในโครงการของคุณ
Yulingtianxia, [email protected]
Blockhook สามารถใช้ได้ภายใต้ใบอนุญาต MIT ดูไฟล์ใบอนุญาตสำหรับข้อมูลเพิ่มเติม
ขอบคุณ mablockclosure และแง่มุม!