我似乎得到了很多像这样的崩溃报告:
Crashed Thread: 14
Exception Type: EXC_GUARD
Exception Codes: 0x4000000200000000, 0x00007fff96f73c48
Thread 14 Crashed:
0 libsystem_kernel.dylib 0x00007fff97b7213a dup + 10
1 com.apple.Foundation 0x00007fff8a116cee -[NSConcreteTask launchWithDictionary:] + 2457
2 com.mycompany.myapp 0x0000000100022814 +[MCSoftwareUpdate automaticallyCheckForUpdates] + 352
3 com.apple.Foundation 0x00007fff89fed76b __NSThread__main__ + 1318
4 libsystem_pthread.dylib 0x00007fff8d2e4899 _pthread_body + 138
5 libsystem_pthread.dylib 0x00007fff8d2e472a _pthread_start + 137
6 libsystem_pthread.dylib 0x00007fff8d2e8fc9 thread_start + 13
它不会影响上述方法 - 它会影响使用NSTask
的任何代码。我做了一些研究,并建议修复权限可以解决问题,但这不是很有用,因为我无法与报告这些崩溃的用户联系。我已经将代码放在try catch块中 - 我还能做些什么来最小化或消除它?
我编写了以下函数来包装NSTask
。
代码:
+ (BOOL)runTask:(NSString*)taskPath arguments:(NSArray*)args task:(NSTask**)taskObj
{
if (![[NSFileManager defaultManager] isExecutableFileAtPath:taskPath] || [[NSWorkspace sharedWorkspace] isFilePackageAtPath:taskPath]) {
NSLog(@"Error: %@ is not executable",taskPath);
return NO;
}
@try {
NSTask *task = [[NSTask alloc] init];
if (taskObj != NULL) *taskObj = task;
[task setLaunchPath:taskPath];
if (args) [task setArguments:args];
[task setStandardError:[NSFileHandle fileHandleWithNullDevice]];
[task setStandardOutput:[NSFileHandle fileHandleWithNullDevice]];
[task launch];
[task waitUntilExit];
taskObj = nil;
[task release];
return YES;
}
@catch (NSException *exc) {
NSLog(@"Exception running task %@: %@",taskPath,[exc reason]);
}
return NO;
}
答案 0 :(得分:1)
如果重新启动修复了问题,那么似乎最小化文件句柄可能有助于防止此问题。但是,我仍然会尝试在本地重现问题,方法是创建大量文件句柄而不关闭它们,这样你就可以确定是什么导致了崩溃。
我看到你在创建文件句柄时将其作为参数传递。这可以防止您控制何时关闭该文件句柄。我会保留对文件句柄的引用,以便您可以在不再使用时关闭它:
NSFileHandle *errorFileHandle = [NSFileHandle fileHandleWithNullDevice];
[task setStandardError:errorFileHandle];
NSFileHandle *outputFileHandle = [NSFileHandle fileHandleWithNullDevice];
[task setStandardOutput:outputFileHandle];
...
//outputFileHandle is no longer used
[outputFileHandle close];