Verwenden der Ausnahmebehandlung im Vergleich zu NSError in Cocoa Apps

Hallo zusammen. Ich habe die Vorschläge von Apple gelesen, wann / wo / wie NSError und @ try / @ catch / @ endlich verwendet werden sollen. Mein Eindruck ist im Wesentlichen, dass Apple es für das Beste hält, die Verwendung von Sprachkonstrukten zur Ausnahmebehandlung zu vermeiden, außer als Mechanismus zum Anhalten der Programmausführung in unerwarteten Fehlersituationen (könnte jemand ein Beispiel für eine solche Situation nennen?)

Ich komme aus Java, wo Ausnahmen der Weg sind, wenn man mit Fehlern umgehen will. Zugegeben, ich bin immer noch im Java-Gedankenraum, aber ich komme langsam mit allem klar, was NSError zu bieten hat.

Eine Sache, bei der ich aufgelegt bin, ist die Aufgabe, den Speicher aufzuräumen, wenn ein Fehler auftritt. In vielen Situationen (z. B. bei Verwendung von C-, C ++ - Bibliotheken, CoreFoundation usw.) muss viel Speicher aufgeräumt werden, bevor eine Funktion aufgrund eines Fehlers abgebrochen werden kann.

Hier ist ein Beispiel, das ich ausgearbeitet habe und das genau die Situationen widerspiegelt, denen ich begegnet bin. Unter Verwendung einiger imaginärer Datenstrukturen öffnet die Funktion ein Dateihandle und erstellt ein 'MyFileRefInfo'-Objekt, das Informationen darüber enthält, was mit der Datei geschehen soll. Einige Dinge werden mit der Datei erledigt, bevor das Dateihandle geschlossen und der Speicher für die Struktur freigegeben wird. Mit Apples Vorschlägen habe ich diese Methode:

- (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;

}

Nun .. meine Java-Logik sagt mir, dass es besser wäre, dies als try / catch / finally-Struktur einzurichten und alle Aufrufe zu platzieren, um das Dateihandle zu schließen und Speicher im finally-Block freizugeben.

Wie so ..

    ...

    @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;

Bin ich verrückt nach dem Gedanken, dass dies eine viel elegantere Lösung mit weniger redundantem Code ist? Habe ich etwas verpasst?

Antworten auf die Frage(4)

Ihre Antwort auf die Frage