Posts

Post marked as solved
3 Replies
1.3k Views
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: @import ObjectiveC; @import UIKit; @import XCTest; static BOOL class_addMethodSuccedeed; static BOOL UINavigationBarDidMoveToWindowCalled; @interface TestCrashTests : XCTestCase @end @implementation TestCrashTests (void)testClassAddMethod { &#9;&#9;XCTAssertTrue(class_addMethodSuccedeed); &#9;&#9;[[[UINavigationBar alloc] initWithFrame:CGRectZero] didMoveToWindow]; &#9;&#9;XCTAssertTrue(UINavigationBarDidMoveToWindowCalled); } (void)swizzle:(Class)class methodName:(NSString*)methodName { &#9;&#9;SEL originalMethod = NSSelectorFromString(methodName); &#9;&#9;SEL newMethod = NSSelectorFromString([NSString stringWithFormat:@"%@%@", @"override_", methodName]); &#9;&#9;&#9;&#9;[self swizzle:class from:originalMethod to:newMethod]; } (void)swizzle:(Class)class from:(SEL)original to:(SEL)new { &#9;&#9;Method originalMethod = class_getInstanceMethod(class, original); &#9;&#9;Method newMethod = class_getInstanceMethod(class, new); &#9;&#9;if (class_addMethod(class, original, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) { &#9;&#9;&#9;&#9;class_replaceMethod(class, new, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); &#9;&#9;&#9;&#9;class_addMethodSuccedeed = YES; &#9;&#9;} else { &#9;&#9;&#9;&#9;method_exchangeImplementations(originalMethod, newMethod); &#9;&#9;} } (void)load { &#9;&#9;static dispatch_once_t onceToken; &#9;&#9;dispatch_once(&amp;onceToken, ^{ &#9;&#9;&#9;&#9;[self swizzle:[UINavigationBar class] methodName:@"didMoveToWindow"]; &#9;&#9;&#9;&#9;[self swizzle:[UIView class] methodName:@"didMoveToWindow"]; &#9;&#9;}); } @end @implementation UIView (Swizzle) (void)override_didMoveToWindow { &#9;&#9;[self override_didMoveToWindow]; } @end @implementation UINavigationBar (Swizzle) (void)override_didMoveToWindow { &#9;&#9;UINavigationBarDidMoveToWindowCalled = YES; &#9;&#9;[self override_didMoveToWindow]; } @end This seems, now, to swizzle wrongly methods of a subclass and in fact create an infinite recursive loop. Any ideas?
Posted Last updated
.