Эй, все. Я читал рекомендации Apple о том, когда/где/как использовать NSError по сравнению с @try/@catch/@. По сути, у меня сложилось впечатление, что Apple думает, что лучше избегать использования языковых конструкций обработки исключений, кроме как механизма остановки выполнения программы в неожиданных ситуациях с ошибками (может быть, кто-то мог бы привести пример такой ситуации?)
Я прихожу из Java, где исключения - это путь, когда нужно обрабатывать ошибки. По общему признанию, я все еще в Java-пространстве, но я медленно приступаю к работе со всем, что может предложить NSError.
Одна вещь, которую я повесил, - это задача очистки памяти при возникновении ошибки. Во многих ситуациях (например, с использованием библиотек C, С++, CoreFoundation и т.д.) У вас много очистки памяти, которая должна быть выполнена до выхода из функции из-за ошибки.
Вот пример, который я приготовил, который точно отражает ситуации, с которыми я сталкивался. Используя некоторые воображаемые структуры данных, функция открывает дескриптор файла и создает объект MyFileRefInfo, который содержит информацию о том, что делать с файлом. Некоторые вещи делаются с файлом до того, как дескриптор файла закрыт, и память для освобожденной структуры. Используя предложения Apple, у меня есть этот метод:
- (BOOL)doSomeThingsWithFile:(NSURL *)filePath error:(NSError **)error
{
MyFileReference inFile; // Lets say this is a CF struct that opens a file reference
MyFileRefInfo *fileInfo = new MyFileRefInfo(...some init parameters...);
OSStatus err = OpenFileReference((CFURLRef)filePath ,&inFile);
if(err != NoErr)
{
*error = [NSError errorWithDomain:@"myDomain" code:99 userInfo:nil];
delete fileInfo;
return NO;
}
err = DoSomeStuffWithTheFileAndInfo(inFile,fileInfo);
if(err != NoErr)
{
*error = [NSError errorWithDomain:@"myDomain" code:100 userInfo:nil];
CloseFileHandle(inFile); // if we don't do this bad things happen
delete fileInfo;
return NO;
}
err = DoSomeOtherStuffWithTheFile(inFile,fileInfo);
if(err != NoErr)
{
*error = [NSError errorWithDomain:@"myDomain" code:101 userInfo:nil];
CloseFileHandle(inFile); // if we don't do this bad things happen
delete fileInfo;
return NO;
}
CloseFileHandle(inFile);
delete fileInfo;
return YES;
}
Теперь... моя Java-логика говорит мне, что было бы лучше установить это как структуру try/catch/finally и поместить все вызовы, чтобы закрыть дескриптор файла и освободить память в блоке finally.
Так вот..
...
@try
{
OSStatus err = OpenFileReference((CFURLRef)filePath ,&inFile);
if(err != NoErr)
{
... throw some exception complete with error code and description ...
}
err = DoSomeStuffWithTheFileAndInfo(inFile,fileInfo);
if(err != NoErr)
{
... throw some exception ...
}
... etc ...
}
@catch(MyException *ex)
{
*error = [NSError errorWithDomain:@"myDomain" code:[ex errorCode] userInfo:nil];
return NO;
}
@finally
{
CloseFileHandle(inFile); // if we don't do this bad things happen
delete fileInfo;
}
return YES;
Неужели я сумасшедший, думая, что это гораздо более элегантное решение с меньшим избыточным кодом? Я что-то пропустил?