iOS 9中Objective-C中的高级方法swizzling



问题很简单。我需要和往常一样的方法-如何用iOS9中的@selector(presentViewController:animated:completion:)替换原来的方法?它只能在iOS9模拟器中工作,不能在实际设备中工作。

是的,这个代码被调用了,但随后您得到了EXC_BAD_ACCESS

为了测试它,我从"主细节模板"创建了一个测试应用程序,添加了一个按钮并添加了以下代码:

UIViewController *vc = [[UIViewController alloc] init];
[self.navigationController presentViewController:vc animated:YES completion:nil];

更新

@implementation UINavigationController (Extension)
- (void)swizzledPresentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion
{
    [ self swizzledPresentViewController:viewControllerToPresent animated:flag completion:completion ];
}
#pragma mark -
+ (void)swizzle:(Class)class oldSelector:(SEL)old newSelector:(SEL)new
{
    Method oldMethod = class_getInstanceMethod(class, old);
    Method newMethod = class_getInstanceMethod(class, new);

    if(class_addMethod(class, old, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
    {
        class_replaceMethod(class, new, method_getImplementation(oldMethod), method_getTypeEncoding(oldMethod));
    }
    else
    {
        method_exchangeImplementations(oldMethod, newMethod);
    }
}
+ (void)load
{
    [self swizzle:UINavigationController.class oldSelector:@selector(presentViewController:animated:completion:) newSelector:@selector(swizzledPresentViewController:animated:completion:)];
}
@end

NSHipster网站上写着几乎相同的代码

更新

警告这个错误在非常随机的设备上重现(在我的情况下是iphone5+ios9.0,但其他用户有更新的设备和ios9.1)。

问题在于快速中断检查nil值。这种情况的解决方案:

1) 检查块是否为nil,然后将其替换为空的非零块

2) 使用现成的库。我尝试过:https://github.com/rabovik/RSSwizzle

最新更新