AspectsIs the old iOS AOP library

Aspects mainly uses forwardInvocation for forwarding. In fact, Aspects uses a similar principle as kvo to dynamically create subclasses by pointing the isa pointer to the created subclass. Then replace the IMP from the subclass with __ASPECTS_ARE_BEING_CALLED__, and add an Aspects_XX method to the subclass, assuming the hook method name is XX. Then the IMP of Aspects_XX is pointed to the IMP of the original XX method, which is easy to call the original method, and then the IMP of the method to hook is pointed to _objc_msgForward, which enters the message forwarding process. The IMP from the forwardInvocation is replaced with __ASPECTS_ARE_BEING_CALLED__, which goes to __ASPECTS_ARE_BEING_CALLED__ for interception

Message Forwarding Flowchart

AOP framework Aspects implementation principles

StingerEle. me open source AOP library

Manual message forwarding is not used. Parses the original method signature and uses ffi_cloSURE_alloc in libffi to construct a “function” — _stingerIMP that matches the original method parameter, replacing the original method function pointer; In addition, the parameter templates CIF and blockCif for the call to the original method and Block are generated. Void st_FFi_function (ffi_cif *cif, void *ret, void **args, void *userdata); The original method implementation and slice block are called based on CIF mainly through FFi_call.

Use libffi to implement AOP

Method Swizzling

Method originalMethod = class_getInstanceMethod([self class], originalSelector);
    Method swizzledMethod = class_getInstanceMethod([self class], swizzledSelector);
    
    BOOL didAddMethod =
    class_addMethod([self class],
                    originalSelector,
                    method_getImplementation(swizzledMethod),
                    method_getTypeEncoding(swizzledMethod));
    
    if (didAddMethod) {
        class_replaceMethod([self class],
                            swizzledSelector,
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
Copy the code

fishhook

Fishhook: In addition to hook C functions, Fishhook + assembly can also hook objc_msgSend.

Cydia Substrate

Cydia Substrate is a Hook based code modification framework that can be used on Android and iOS platforms to modify system default code.

Method swizzling/Aspects/Stinger contrast

Compare the item swizzling Aspects Stinger
speed Very fast slow Very fast
Api friendliness Very poor Very good Very good
Type of hook support support support
The hook of the instance object Does not support support support
Change selector when calling the original method Modify the Modify the Do not change the
Methods may have name conflicts will Don’t Don’t
Compatible with other hook methods (RAC, JSPactch…) Compatible with Are not compatible Compatible with
Support multithreading to increase hook Your lock support support
Hook predictability, traceability Very poor good Very good
Modify the parent method implementation May be Don’t Don’t

Reference: How much faster Stinger can be than Aspects