4

質問は簡単です。いつもと同じことが必要です-元のメソッドを私のものに置き換える方法はありますが@selector(presentViewController:animated:completion:)、iOS9では? 実際のデバイスではなく、iOS9 シミュレータでのみ動作します。

はい、このコードが呼び出されますが、取得しEXC_BAD_ACCESSます。

それをテストするために、「Master-Detail テンプレート」からテスト アプリを作成し、ボタンを追加し、次のコードを追加しました。

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 を使用しています)。

4

1 に答える 1

2

問題は、スウィズリングがnil値のチェックを中断することです。この場合の解決策:

1)ブロックかどうかを確認nilしてから、空の非 nil ブロッ​​クに置き換えます

2) 既製のライブラリを使用します。私が試した:https://github.com/rabovik/RSSwizzle

于 2015-11-23T09:50:46.927 に答える