Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Objective-C中使用高级方法swizzling,iOS 9?_Ios_Objective C_Uiviewcontroller_Modalviewcontroller_Method Swizzling - Fatal编程技术网

在Objective-C中使用高级方法swizzling,iOS 9?

在Objective-C中使用高级方法swizzling,iOS 9?,ios,objective-c,uiviewcontroller,modalviewcontroller,method-swizzling,Ios,Objective C,Uiviewcontroller,Modalviewcontroller,Method Swizzling,问题很简单。我需要和平常一样的方法-如何在iOS9中用我的一个但是@选择器(presentViewController:animated:completion:)替换原来的方法?它只能在iOS9模拟器中工作,不能在真实设备中工作 是,调用此代码,但随后您将获得EXC\u BAD\u访问权限 为了测试它,我从“Master Detail template”创建了一个测试应用程序,添加了一个按钮并添加了以下代码: UIViewController *vc = [[UIViewController a

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

是,调用此代码,但随后您将获得
EXC\u BAD\u访问权限

为了测试它,我从“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网站上也写了几乎相同的代码

已更新

@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

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

问题是滑动中断检查
nil
值。本案例的解决方案:

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


2) 使用现成的库。我试过:

告诉我们你是如何使用swizzling.Edited方法的。我希望这将有助于找到一个解决方案你的swizzled方法不是无限递归的吗????这部分只是指我调用原始方法。@Avi:Google关于“方法swizzling”。该方法的方法体与“swizzled”方法切换,因此代码实际上调用了原始方法。