Skip to content

yulingtianxia/BlockTracker

Repository files navigation

BlockTracker

CI Status Carthage compatible GitHub release Twitter Follow

BlockTracker

BlockTracker can track block arguments of a method. It's based on BlockHook.

📚 Article

追踪 Objective-C 方法中的 Block 参数对象

🌟 Features

  • Easy to use.
  • Keep your code clear.
  • Let you modify return value and arguments.
  • Trace all block args of method.
  • Trace all NSMallocBlock.
  • Self-managed trackers.
  • Support CocoaPods & Carthage.

🔮 Example

The sample project "BlockTrackerSample" just only support iOS platform.

🐒 How to use

Track blocks in method

You can track blocks in arguments. This method returns a BTTracker instance for more control. You can stop a BTTracker when you don't want to track it anymore.

__unused BTTracker *tracker = [self bt_trackBlockArgOfSelector:@selector(performBlock:) callback:^(BHInvocation * _Nonnull invocation) {
    switch (invocation.mode) {
        case BlockHookModeBefore:
            NSLog(@"Before block:%@, mangleName:%@", invocation.token.block, invocation.token.mangleName);
            break;
        case BlockHookModeAfter:
            NSLog(@"After block:%@, mangleName:%@", invocation.token.block, invocation.token.mangleName);
            objc_setAssociatedObject(invocation.token, @"invoked", @YES, OBJC_ASSOCIATION_RETAIN);
            break;
        case BlockHookModeDead:
            NSLog(@"Block Dead! mangleName:%@", invocation.token.mangleName);
            BOOL invoked = [objc_getAssociatedObject(invocation.token, @"invoked") boolValue];
            if (!invoked) {
                NSLog(@"Block Not Invoked Before Dead! %@", invocation.token.mangleName);
            }
            break;
        default:
            break;
    }
}];
    
// invoke blocks
NSString *word = @"I'm a block";
[self performBlock:^{
    NSLog(@"%@", word);
}];
// stop tracker in future
//    [tracker stop];
// blocks will die

- (void)performBlock:(void(^)(void))block {
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), block);
}

@end

Here is the log:

Hook Block Arg mangleName:__42-[BlockTrackerSampleTests testTrackMethod]_block_invoke_2, in selector:performBlock:
Before block:<__NSMallocBlock__: 0x600000c71aa0>, mangleName:__42-[BlockTrackerSampleTests testTrackMethod]_block_invoke_2
I'm a block
After block:<__NSMallocBlock__: 0x600000c71aa0>, mangleName:__42-[BlockTrackerSampleTests testTrackMethod]_block_invoke_2
Block Dead! mangleName:__42-[BlockTrackerSampleTests testTrackMethod]_block_invoke_2

Track a batch of blocks.

setMallocBlockCallback(^(BHInvocation * _Nonnull invocation) {
    switch (invocation.mode) {
        case BlockHookModeBefore: {
            NSLog(@"Before block:%@, mangleName:%@", invocation.token.block, invocation.token.mangleName);
            break;
        }
        case BlockHookModeAfter: {
            NSLog(@"After block:%@, mangleName:%@", invocation.token.block, invocation.token.mangleName);
            objc_setAssociatedObject(invocation.token, @"invoked", @YES, OBJC_ASSOCIATION_RETAIN);
            break;
        }
        case BlockHookModeDead: {
            NSLog(@"Block Dead! mangleName:%@", invocation.token.mangleName);
            BOOL invoked = [objc_getAssociatedObject(invocation.token, @"invoked") boolValue];
            if (!invoked) {
                NSLog(@"Block Not Invoked Before Dead! %@", invocation.token.mangleName);
            }
            break;
        }
        default:
            break;
    }
});

📲 Installation

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:

$ gem install cocoapods

To integrate BlockTracker into your Xcode project using CocoaPods, specify it in your Podfile:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
target 'MyApp' do
	pod 'BlockTracker'
end

You need replace "MyApp" with your project's name.

Then, run the following command:

$ pod install

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.

You can install Carthage with Homebrew using the following command:

$ brew update
$ brew install carthage

To integrate BlockTracker into your Xcode project using Carthage, specify it in your Cartfile:

github "yulingtianxia/BlockTracker"

Run carthage update to build the framework and drag the built BlockTrackerKit.framework into your Xcode project.

Manual

Just drag source files in BlockTracker folder to your project.

❤️ Contributed

  • If you need help or you'd like to ask a general question, open an issue.
  • If you found a bug, open an issue.
  • If you have a feature request, open an issue.
  • If you want to contribute, submit a pull request.

👨🏻‍💻 Author

yulingtianxia, yulingtianxia@gmail.com

👮🏻 License

BlockTracker is available under the MIT license. See the LICENSE file for more info.