Objective-C、iOS 9 中的高级方法 swizzling?
Advanced method swizzling in Objective-C, iOS 9?
问题很简单。我需要和往常一样 - 如何用我的方法替换原始方法,但 iOS9 中的 @selector(presentViewController:animated:completion:)
?它仅适用于 iOS9 模拟器,不适用于真实设备。
是的,此代码被调用,但随后您得到 EXC_BAD_ACCESS
。
为了测试它,我创建了一个测试应用 "Master-Detail template" 添加了一个按钮并添加了以下代码:
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).
问题是 swizzling 中断了检查 nil
值。这种情况的解决方案:
1) 检查块是否为 nil
然后用空的非零块替换它
2) 使用现成的库。我试过了:https://github.com/rabovik/RSSwizzle
问题很简单。我需要和往常一样 - 如何用我的方法替换原始方法,但 iOS9 中的 @selector(presentViewController:animated:completion:)
?它仅适用于 iOS9 模拟器,不适用于真实设备。
是的,此代码被调用,但随后您得到 EXC_BAD_ACCESS
。
为了测试它,我创建了一个测试应用 "Master-Detail template" 添加了一个按钮并添加了以下代码:
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).
问题是 swizzling 中断了检查 nil
值。这种情况的解决方案:
1) 检查块是否为 nil
然后用空的非零块替换它
2) 使用现成的库。我试过了:https://github.com/rabovik/RSSwizzle