11

我曾经NSFileHandle将数据写入文件。

NSFilehandle *handle = [NSFileHandle fileHandleForWritingAtPath:@"path/of/file"];

@try {
    [handle writedata:data];
} @catch (NSException *e) {
    // when exception occur, never got here 
     NSLog(@"%@", e);
}

由于我的设备磁盘空间已满,调用writedata将失败。但我无法捕捉到异常。

我的程序日志信息:

2014-05-23 16:17:24.435 mytest[12919:3203] An uncaught exception was raised
2014-05-23 16:17:24.435 mytest[12919:3203] *** -[NSConcreteFileHandle writeData:]:
      No space left on device
2014-05-23 16:17:24.436 mytest[12919:3203] (
0 CoreFoundation 0x00007fff8fae725c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff8cbb3e75 objc_exception_throw + 43
2 CoreFoundation 0x00007fff8fae710c +[NSException raise:format:] + 204
3 Foundation 0x00007fff93640f31 __34-[NSConcreteFileHandle writeData:]_block_invoke + 84
4 Foundation 0x00007fff93840020 __49-[_NSDispatchData enumerateByteRangesUsingBlock:]_block_invoke + 32
5 libdispatch.dylib 0x00007fff8bfc2fad _dispatch_client_callout3 + 9
6 libdispatch.dylib 0x00007fff8bfc2f28 _dispatch_data_apply + 113
7 libdispatch.dylib 0x00007fff8bfc9502 dispatch_data_apply + 31
8 Foundation 0x00007fff9383fff9 -[_NSDispatchData enumerateByteRangesUsingBlock:] + 83
9 Foundation 0x00007fff93640ed2 -[NSConcreteFileHandle writeData:] + 150
10 ZiSyncMac 0x000000010000b1eb -[TransferFile writePart:data:] + 475

我发现writedata调用了一个调度来对文件系统进行真正的写入数据。所以我认为writedata会在 GCD 中抛出异常。

如何在我的代码中处理 GCD 异常?

4

2 回答 2

1

来自一个被劫持的网站(因此没有提供链接,但解释仍然有用):

seekToEndOfFile() 和 writeData() 没有被标记为 throws(它们不会抛出一个可以用 do-try-catch 块捕获的 NSError 对象),这意味着在 Swift 的当前状态下,它们引发的 NSExceptions不能被“抓住”。

如果您正在处理 Swift 项目,则可以创建一个 Objective-C 类,该类实现捕获 NSExceptions 的 NSFileHandle 方法(就像在这个问题中一样),否则您就不走运了。

于 2018-02-09T14:52:10.297 回答
0

@eric 说的是对的。但是,您可以做的是在写入之前检查磁盘中剩余多少空间,并且仅在写入磁盘之后检查。

于 2018-12-24T09:46:13.097 回答