1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- #import <objc/runtime.h>
- #import "ReactorKitRuntime.h"
- @implementation NSObject (ReactorKit)
- + (void)load {
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- [self swizzleInitializeOfClassNamed:@"UIViewController"];
- #if !TARGET_OS_MACCATALYST
- [self swizzleInitializeOfClassNamed:@"NSViewController"];
- #endif
- });
- }
- + (void)swizzleInitializeOfClassNamed:(NSString *)className {
- Class class = NSClassFromString(className);
- if (!class) {
- return;
- }
- method_exchangeImplementations(class_getClassMethod(class, @selector(initialize)),
- class_getClassMethod(self, @selector(_reactorkit_initialize)));
- }
- + (void)_reactorkit_initialize {
- [self _reactorkit_initialize];
- BOOL isUIViewController = [self isSubclassOfClassNamed:@"UIViewController"];
- BOOL isNSViewController = [self isSubclassOfClassNamed:@"NSViewController"];
- if (!isUIViewController && !isNSViewController) {
- return;
- }
- [self swizzleViewDidLoad];
- }
- + (void)swizzleViewDidLoad {
- Class class = self;
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wundeclared-selector"
- SEL oldSelector = @selector(viewDidLoad);
- SEL performBindingSelector = @selector(_reactorkit_performBinding);
- #pragma clang diagnostic pop
- Method oldMethod = class_getInstanceMethod(class, oldSelector);
- const char *types = method_getTypeEncoding(oldMethod);
- void (*oldMethodImp)(id, SEL) = (void (*)(id, SEL))method_getImplementation(oldMethod);
- IMP newMethodImp = imp_implementationWithBlock(^(__unsafe_unretained id self) {
- oldMethodImp(self, oldSelector);
- if ([self respondsToSelector:performBindingSelector]) {
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
- [self performSelector:performBindingSelector];
- #pragma clang diagnostic pop
- }
- });
- class_replaceMethod(class, oldSelector, newMethodImp, types);
- }
- + (BOOL)isSubclassOfClassNamed:(NSString *)className {
- Class superclass = NSClassFromString(className);
- if (!superclass) {
- return NO;
- }
- return [self isSubclassOfClass:superclass];
- }
- @end
|