ReactorKitRuntime.m 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. #import <objc/runtime.h>
  2. #import "ReactorKitRuntime.h"
  3. @implementation NSObject (ReactorKit)
  4. + (void)load {
  5. static dispatch_once_t onceToken;
  6. dispatch_once(&onceToken, ^{
  7. [self swizzleViewDidLoadOfClassNamed:@"UIViewController"];
  8. #if !TARGET_OS_MACCATALYST
  9. [self swizzleViewDidLoadOfClassNamed:@"NSViewController"];
  10. #endif
  11. });
  12. }
  13. + (void)swizzleViewDidLoadOfClassNamed:(NSString *)className {
  14. Class class = NSClassFromString(className);
  15. if (!class) {
  16. return;
  17. }
  18. #pragma clang diagnostic push
  19. #pragma clang diagnostic ignored "-Wundeclared-selector"
  20. SEL oldSelector = @selector(viewDidLoad);
  21. SEL performBindingSelector = @selector(_reactorkit_performBinding);
  22. #pragma clang diagnostic pop
  23. Method oldMethod = class_getInstanceMethod(class, oldSelector);
  24. const char *types = method_getTypeEncoding(oldMethod);
  25. void (*oldMethodImp)(id, SEL) = (void (*)(id, SEL))method_getImplementation(oldMethod);
  26. IMP newMethodImp = imp_implementationWithBlock(^(__unsafe_unretained id self) {
  27. oldMethodImp(self, oldSelector);
  28. if ([self respondsToSelector:performBindingSelector]) {
  29. #pragma clang diagnostic push
  30. #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
  31. [self performSelector:performBindingSelector];
  32. #pragma clang diagnostic pop
  33. }
  34. });
  35. class_replaceMethod(class, oldSelector, newMethodImp, types);
  36. }
  37. + (BOOL)isSubclassOfClassNamed:(NSString *)className {
  38. Class superclass = NSClassFromString(className);
  39. if (!superclass) {
  40. return NO;
  41. }
  42. return [self isSubclassOfClass:superclass];
  43. }
  44. @end