iOS hook a method not implemented by an instance

 

Situation: We need to hook the proxy object of the tableview 

 ( void )tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath method, do something when executing this method,

However, if the proxy object of the tableview does not implement this method, what should we do? The solution is, we judge in the tool class, if the proxy object does not implement the method

We add an implementation to the proxy object, so that we can hook this method, and then do what we want to achieve at the appropriate time, here, we can implement a method we did ourselves

Analogy is used as an "introduction", he is just playing the role of an "introduction", and there is no specific implementation, but it won't work without him, here in the tool class + (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell * )cell forRowAtIndexPath:(NSIndexPath *)indexPath method is "Introduction"

+ (void)hookWillDisplayCellWithPresenter:(NSObject *)presenter
{
    [presenter aspect_hookSelector:@selector(tableView:willDisplayCell:forRowAtIndexPath:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> data) {
        if (data.arguments.count < 2) {
            return;
        }
        UITableView *tableView = data.arguments.firstObject;
        UITableViewCell *cell = data.arguments[1];
        if (![tableView isKindOfClass:[UITableView class]] ||
            ![cell isKindOfClass:[UITableViewCell class]]) {
            return;
        }

        [tableView bringSubviewToFront:cell];
    } error:nil];
}

The above is the implementation of the hook method, and the following is to determine whether it is implemented. If it is not implemented, add one of your own methods to the object as a primer

+ (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"执行执行之星");
}
            NSObject *presenter = scrollView.delegate;
            if ([presenter respondsToSelector:@selector(tableView:willDisplayCell:forRowAtIndexPath:)]) {
                [self hookWillDisplayCellWithPresenter:presenter];
            } else {
                IMP tmpImp = [self methodForSelector:@selector(tableView:willDisplayCell:forRowAtIndexPath:)];
                BOOL result = class_addMethod([presenter class], @selector(tableView:willDisplayCell:forRowAtIndexPath:),tmpImp, [@"v@:@@@" UTF8String]);
                if (result) {
                    [self hookWillDisplayCellWithPresenter:presenter];
                }
            }
        }

Note that these three pieces of code are all implemented in the same class. The bottom piece of code is also in a class method. Here is a method of hooking presenter in a class method that may not be implemented. If it is not implemented,

This class will help him realize it, so as to trigger the hooked method of present at an appropriate time to achieve our purpose of capturing the opportunity 

 

Guess you like

Origin blog.csdn.net/LIUXIAOXIAOBO/article/details/112885476
Recommended