我在浏览SKStoreProductViewController上的viewWillAppear或viewDidAppear时遇到了麻烦。我需要知道它的子类何时由第三方库提供。
我使用的代码是:
- (void)swizzleFunnyStoreProductControllerAppear {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
SEL originalSelector = @selector(viewWillAppear:);
SEL swizzledSelector = @selector(skViewDidAppearNotification:);
NSString *viewControllerClassString = @"SKStoreProductViewController";
Method originalMethod = class_getInstanceMethod(NSClassFromString(viewControllerClassString), originalSelector);
Method swizzledMethod = class_getInstanceMethod([self class], swizzledSelector);
BOOL didAddMethod =
class_addMethod(NSClassFromString(viewControllerClassString),
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(NSClassFromString(viewControllerClassString),
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
- (void)skViewDidAppearNotification:(BOOL)animated {
[[NSNotificationCenter defaultCenter] postNotificationName:ALFunnyViewControllerDidAppearNotification object:NSStringFromClass([self class])];
// calling the original method that is under the replaced name.
[self skViewDidAppearNotification:animated];
}
运行时,我得到:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[FunnySKStoreProductViewControllerSubClass skViewDidAppearNotification:]: unrecognized selector sent to instance 0x144f1b830'
在[self skViewDidAp ....]中使用断点显示响应选择器的类:
(lldb) po [self respondsToSelector:@selector(viewWillAppear:)]
true
(lldb) po [self respondsToSelector:@selector(viewDidAppear:)]
true
(lldb) po [self respondsToSelector:@selector(skViewDidAppearNotification:)]
false
(lldb) po [self respondsToSelector:@selector(skViewDidDisappearNotification:)]
true
我无法弄清楚为什么DidAppear的didAddMethod == NO,以及为什么它在DidDisappear的同一个类上工作?
答案 0 :(得分:1)
我认为SKStoreProductViewController
是使用远程XPC服务。
因此,您无法处理应用中的任何内容。
它可以通过其他系统进程处理。
如果您在recursiveDescription
storeProductViewController.view
您可以找到_UIRemoteView
。