Привет всем. Я читал предложения Apple о том, когда / где / как использовать NSError против @ try / @ catch / @ наконец. По сути, у меня сложилось впечатление, что Apple считает, что лучше избегать использования языковых конструкций обработки исключений, кроме как в качестве механизма для остановки выполнения программы в непредвиденных ситуациях с ошибками (может быть, кто-то может привести пример такой ситуации?)
Я пришел из Java, где исключения - это путь, когда нужно обрабатывать ошибки. По общему признанию, я все еще нахожусь в пространстве мыслей Java, но я постепенно осваиваю все, что может предложить NSError.
Одна вещь, от которой я зависаю, - это очистка памяти при возникновении ошибки. Во многих ситуациях (например, с использованием библиотек C, 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;
Неужели я схожу с ума от мысли, что это гораздо более элегантное решение с менее избыточным кодом?
Я что-то пропустил?