steipete / Aspects

Delightful, simple library for aspect oriented programming in Objective-C and Swift.
https://twitter.com/steipete
MIT License
8.4k stars 1.26k forks source link

`doesNotRecognizeSelector` after removing hooks of subclass #155

Open JerryChu opened 5 years ago

JerryChu commented 5 years ago

sample project: Aspect_issue.zip

  1. add a hook for superclass, e.g. UIViewController

    [UIViewController aspect_hookSelector:@selector(viewDidAppear:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info) {
        NSLog(@"hooked viewDidAppear!");
    } error:NULL];
  2. add a hook for subclass, e.g. ViewController

    id<AspectToken> token = [ViewController aspect_hookSelector:@selector(foo) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info) {
        NSLog(@"hooked foo!");
    } error:NULL];
  1. remove the hook of subclass
    [token remove];

Then, when ViewController's [super viewDidAppear:] is called, it will trigger a doesNotRecognizeSelector crash.

It is because that when the hook token is removed from ViewController, Aspect finds ViewController has no hooks, so aspect_undoSwizzleForwardInvocation is called, resetting ViewController's forwardInvocation to the original method (which is nil, and Aspect uses NSObject's forwardInvocation implementation instead ).