Hi all,
I incurred into a change of behavior that is not documented, so I am not sure if it is an issue or it is expected.
In particular, calling class_addMethod started to return false for some UIKit related classes on iOS 14 Beta while on iOS <13.5 was returning true.
A tests that shows the change in behavior, that succeed on iOS 13.5 and fails on iOS 14 Beta is the following:
This seems, now, to swizzle wrongly methods of a subclass and in fact create an infinite recursive loop.
Any ideas?
I incurred into a change of behavior that is not documented, so I am not sure if it is an issue or it is expected.
In particular, calling class_addMethod started to return false for some UIKit related classes on iOS 14 Beta while on iOS <13.5 was returning true.
A tests that shows the change in behavior, that succeed on iOS 13.5 and fails on iOS 14 Beta is the following:
Code Block language @import ObjectiveC; @import UIKit; @import XCTest; static BOOL class_addMethodSuccedeed; static BOOL UINavigationBarDidMoveToWindowCalled; @interface TestCrashTests : XCTestCase @end @implementation TestCrashTests - (void)testClassAddMethod { XCTAssertTrue(class_addMethodSuccedeed); [[[UINavigationBar alloc] initWithFrame:CGRectZero] didMoveToWindow]; XCTAssertTrue(UINavigationBarDidMoveToWindowCalled); } + (void)swizzle:(Class)class methodName:(NSString*)methodName { SEL originalMethod = NSSelectorFromString(methodName); SEL newMethod = NSSelectorFromString([NSString stringWithFormat:@"%@%@", @"override_", methodName]); [self swizzle:class from:originalMethod to:newMethod]; } + (void)swizzle:(Class)class from:(SEL)original to:(SEL)new { Method originalMethod = class_getInstanceMethod(class, original); Method newMethod = class_getInstanceMethod(class, new); if (class_addMethod(class, original, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) { class_replaceMethod(class, new, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); class_addMethodSuccedeed = YES; } else { method_exchangeImplementations(originalMethod, newMethod); } } + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ [self swizzle:[UINavigationBar class] methodName:@"didMoveToWindow"]; [self swizzle:[UIView class] methodName:@"didMoveToWindow"]; }); } @end @implementation UIView (Swizzle) - (void)override_didMoveToWindow { [self override_didMoveToWindow]; } @end @implementation UINavigationBar (Swizzle) - (void)override_didMoveToWindow { UINavigationBarDidMoveToWindowCalled = YES; [self override_didMoveToWindow]; } @end
This seems, now, to swizzle wrongly methods of a subclass and in fact create an infinite recursive loop.
Any ideas?