@implementation zzFlowMonitor
......
void applicationFlowMonitor_original(id selfApp, SEL selector,UIApplication *app, CH_T completionHandler)
{
NSLog(@"applicationFlowMonitor_original to do something...");
completionHandler(UIBackgroundFetchResultNewData);
}
-(void) applicationFlowMonitor_swizzling:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
[[zzFlowMonitor shareInstance] refreshBackFetchHandle];
NSLog(@"applicationFlowMonitor_swizzling to do something...");
//call performFetchWithCompletionHandler delegate in appDelegate.
//an error occurred.*********************************************
[self applicationFlowMonitor_swizzling:application performFetchWithCompletionHandler:completionHandler];
}
-(void)startFlowMonitor:(Class)cla NS_AVAILABLE_IOS(7_0)
{
static dispatch_once_t oncetoken;
dispatch_once(&oncetoken, ^{
[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
Method performFetchWCH = class_getInstanceMethod(cla, @selector(application:performFetchWithCompletionHandler:));
BOOL didAddMethod = class_addMethod(cla, @selector(application:performFetchWithCompletionHandler:), (IMP)applicationFlowMonitor_original, method_getTypeEncoding(performFetchWCH));
if(!didAddMethod){
SEL swizzledSelector = @selector(applicationFlowMonitor_swizzling:performFetchWithCompletionHandler:);
Method swizzledMethod = class_getInstanceMethod([zzFlowMonitor class], swizzledSelector);
method_exchangeImplementations(performFetchWCH, swizzledMethod);
}
});
}
@end
在AppDelegate.h文件中打击: @implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[zzFlowMonitor shareInstance] startFlowMonitor:[AppDelegate class]];
return YES;
}
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^) (UIBackgroundFetchResult))completionHandler {
NSLog(@"application to do something...");
completionHandler(UIBackgroundFetchResultNewData);
}
@end
错误消息打击:
2015-08-10 14:26:44.256 FlowHome[18120:3350484] -[AppDelegate applicationFlowMonitor_swizzling:performFetchWithCompletionHandler:]: unrecognized selector sent to instance 0x7fc8386077f0
2015-08-10 14:26:44.259 FlowHome[18120:3350484] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[AppDelegate applicationFlowMonitor_swizzling:performFetchWithCompletionHandler:]: unrecognized selector sent to instance 0x7fc8386077f0'
*** First throw call stack:
(
0 CoreFoundation 0x0000000105da0c65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000105a39bb7 objc_exception_throw + 45
2 CoreFoundation 0x0000000105da80ad -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x0000000105cfe13c ___forwarding___ + 988
4 CoreFoundation 0x0000000105cfdcd8 _CF_forwarding_prep_0 + 120
5 FlowHome 0x00000001053dbfd5 -[zzFlowMonitor applicationFlowMonitor_swizzling:performFetchWithCompletionHandler:] + 197
6 UIKit 0x00000001061a8c59 -[UIApplication _handleNonLaunchSpecificActions:forScene:withTransitionContext:] + 671
7 UIKit 0x00000001061ace31 __88-[UIApplication _handleApplicationLifecycleEventWithScene:transitionContext:completion:]_block_invoke + 196
8 UIKit 0x00000001061acd5e -[UIApplication _handleApplicationLifecycleEventWithScene:transitionContext:completion:] + 349
9 UIKit 0x00000001061977ba -[UIApplication scene:didUpdateWithDiff:transitionContext:completion:] + 486
10 FrontBoardServices 0x00000001088485e5 __31-[FBSSerialQueue performAsync:]_block_invoke_2 + 21
11 CoreFoundation 0x0000000105cd441c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
12 CoreFoundation 0x0000000105cca165 __CFRunLoopDoBlocks + 341
13 CoreFoundation 0x0000000105cc9f25 __CFRunLoopRun + 2389
14 CoreFoundation 0x0000000105cc9366 CFRunLoopRunSpecific + 470
15 GraphicsServices 0x00000001091b4a3e GSEventRunModal + 161
16 UIKit 0x00000001061998c0 UIApplicationMain + 1282
17 FlowHome 0x00000001053dc22f main + 111
18 libdyld.dylib 0x0000000107593145 start + 1
19 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
我知道AppDelegate.m中没有applicationFlowMonitor_swizzling方法,但我不知道如何解决它,我需要在不同的界面中替换方法。 zzFlowMonitor是一个库,我想在我的库中挂钩后台获取事件。非常感谢。
答案 0 :(得分:0)
简而言之,如果你想通过这种方式工作,你需要改为:
-(void) applicationFlowMonitor_swizzling:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
[[zzFlowMonitor shareInstance] refreshBackFetchHandle];
NSLog(@"applicationFlowMonitor_swizzling to do something...");
//call performFetchWithCompletionHandler delegate in appDelegate.
//an error occurred.*********************************************
[[zzFlowMonitor sharedInstance] applicationFlowMonitor_swizzling:application performFetchWithCompletionHandler:completionHandler];
}
您正在交换这两种方法的实现,因此self
将成为您的应用委托,但由于您从不添加该方法,因此不会有签名-(void) applicationFlowMonitor_swizzling:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
的方法。该方法在zzFlowMonitor
中停止,但其实现将是您的应用委托中定义的- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^) (UIBackgroundFetchResult))completionHandler
的实现。