问题:
XPC 似乎有自己的@try @catch 块,它在方法中捕获未处理的异常,记录异常,然后记录调用-[NSXPCConnection interruptionHandler]
。
此问题在rdar://48543049下报告给 Apple 。
注意:这些不是复制和过去的解决方案,请仔细评估您的崩溃报告框架。我链接到PLCrashReporter的实现细节。
解决方案 A:
@try @catch 块:
- (void)upperCaseString:(NSString *)aString withReply:(void (^)(NSString *))reply {
@try {
NSArray *array = [NSArray array];
reply([array objectAtIndex:23]);
} @catch (NSException *exception) {
NSUncaughtExceptionHandler *handler = NSGetUncaughtExceptionHandler();
if (handler) {
handler(exception);
}
}
}
讨论
HockeyApp使用PLCrashReporter进行崩溃报告。PLCrashReporter注册一个NSUncaughtExceptionHandler
(代码)。所以上面的代码会将异常转发给PLCrashReporter异常处理程序并终止(代码)XPC。
Mattie建议再次@throw异常,以触发内部 XPC @catch块以及可能的内部清理和日志记录。这是要考虑的事情。特别是如果您在连接的 LaunchAgent/Server 端有自interruptionHandler
定义NSXPCConnection
!
现在我支持不再扔它,因为我的XPC 是完全无状态的,只要崩溃就可以了。
解决方案 A的缺点是通过 XPC 公开的每个方法都需要这个@try @catch 块。
解决方案 B:
使用NSProxy
捕获所有未处理异常的a NSXPCConnection exportObject
:
@interface LOUncaughtExceptionHandlerProxy : NSProxy {
NSObject *_object;
}
@end
@implementation LOUncaughtExceptionHandlerProxy
- (instancetype)initWithObject:(NSObject *)object
{
NSParameterAssert(object);
_object = object;
return self;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
return [_object methodSignatureForSelector:selector];
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
@try {
[invocation invokeWithTarget:_object];
} @catch (NSException *exception) {
NSUncaughtExceptionHandler *handler = NSGetUncaughtExceptionHandler();
if (handler) {
handler(exception);
}
}
}
@end
在NSXPCListener
侦听器中设置:
- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection {
XPC *exportedObject = [XPC new];
LOUncaughtExceptionHandlerProxy *proxy = [[LOUncaughtExceptionHandlerProxy alloc] initWithObject:exportedObject];
newConnection.exportedObject = proxy;
newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(XPCProtocol)];
[newConnection resume];
return YES;
}
解决方案 A 的所有细节都适用于解决方案B。
解决方案 Z:
在 macOS 上可以使用ExceptionHandling.framework ,它的问题在BITCrashExceptionApplication.h中有很好的概述。
讨论
如果框架没有移植到 iOS,这绝不是一个好兆头。另请注意Matties评论:
我与 Apple 的交互直接表明 ExceptionHandling.framework 不再受支持。而且,根据我在 Crashlytics 上工作的经验,它存在一些基本的互操作性问题,超出了引用的标题中指出的问题。