Gibt es einen Grund, warum CFRelease nicht auf NULL prüft? Ist es nicht inakzeptabel, wenn [keine Veröffentlichung]; frei (NULL); lösche NULL; Alles funktioniert einwandfrei?Warum würde CFRelease (NULL) abstürzen?
Antwort
Der Quellcode von CoreFoundation ist öffentlich verfügbar. Insbesondere für Snow Leopard der Code CFRelease ist in http://www.opensource.apple.com/source/CF/CF-550/CFRuntime.c
Hier ist, was der relevante Teil wie folgt aussieht:
void CFRelease(CFTypeRef cf) {
if (NULL == cf) HALT;
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
if (CF_IS_COLLECTABLE(cf)) {
if (CFTYPE_IS_OBJC(cf)) {
// release the GC-visible reference.
auto_zone_release(auto_zone(), (void*)cf);
} else {
// special-case CF objects for better performance.
_CFRelease(cf);
}
return;
}
#endif
}
Das ist nicht Ihre Frage zur Gestaltung Motivationen nicht beantworten, aber sie auch gefragt, warum CFRelease tut nicht auf NULL prüfen. Es überprüft und schlägt absichtlich fehl, wenn NULL als Parameter übergeben wird.
Meine persönliche Überzeugung ist Quinn ähnlich, dass die CF-Designer es als einen Programmierfehler empfanden, NULL zu übergeben.
All diese Funktionen sind Teil von verschiedenen APIs, die verschiedenen Konventionen in Bezug zu folgen NULL
Handhabung:
CFRelease
ist Teil des Corefoundation C SDK, das nichtNULL
Referenz als Argumente standardmäßig akzeptiert. Teil der C++ Bibliothek (libc++
), die ermöglichtNULL
Argumente[nil release]
verwendet Objective-Cfree(NULL)
ist ein Teil der C-Bibliothek (libc
), dieNULL
Argumentdelete NULL
erlaubt (die Dereferenzierungen vonnil
ermöglicht)
Ich denke, die SDK-Autoren CoreFoundation
entschieden, konsistenter zu sein mit dem Rest von SDK und nicht mit ähnlicher Funktion in anderen SDKs.
Guter Punkt, es scheint nicht viel Sinn auf den ersten Blick zu machen. Natürlich, die behavior is properly documented, aber es wäre nett, wenn es würde NULL
anmutig behandeln. Beachten Sie, dass CFRetain
und CFMakeCollectable
(neu in 10.4, GC aktiviert in 10.5) das gleiche Verhalten zeigen. Ich bin nicht mit all den Motivationen vertraut, die es auf diese Weise entworfen haben, aber der Schwerpunkt lag wahrscheinlich eher auf der internen Konsistenz mit dem Rest des CoreFoundation-Frameworks.
Es ist schwierig/unmöglich zu wissen warum CF wurde so entworfen, es sei denn, Sie können einen der Designer fragen. Meine beste Vermutung ist, dass die Designer entschieden haben, dass das Übergeben von NULL für Speicherverwaltungsfunktionen (sollte?) Ein Programmierfehler sein sollte. Man könnte argumentieren, dass das Verursachen eines Absturzes bei NULL ein wünschenswertes "Fail-Fast" Verhalten ist, da Bugs, die fast sofort abstürzen, einfacher zu finden sind als Bugs, die stillschweigend nichts tun, statt wie erwartet. Persönlich bevorzuge ich die Do-Nothing-on-Null-Ansatz, aber ich denke, das ist das Leben ...
Angesichts der Tatsache, dass die API nicht ändern kann/wird, können Sie entweder für NULL testen oder umgehen das Problem Fall. Eine Option könnte darin bestehen, eine Inline-Funktion oder einen Makro zu definieren, der CFRelease nur für Nicht-NULL-Referenzen aufruft. In jedem Fall ist es wahrscheinlich am besten, in Ihrem Code explizit zu sein, um Verwirrung auf der Straße zu vermeiden.
Beachten Sie, dass Quartz CGImageRelease und ähnliche NULL akzeptieren: "Diese Funktion entspricht CFRelease, außer dass es keinen Fehler verursacht, wenn der Bildparameter NULL ist." – IlDan
Richtig, es wäre nett, aber das ist in CoreGraphics, nicht Core Foundation. Wenn CFRelease und Freunde in ** not ** crash geändert wurden, wenn sie NULL übergeben wurde, könnte dies zu unerwarteten Ergebnissen im bestehenden Code führen (obwohl hoffentlich niemand absichtlich so Abstürze verursacht) und CoreFoundation-Programmierer verwirren, die an das Verhalten gewöhnt sind. Trotzdem stimme ich dir zu. –
Sie können sich den Quellcode von CFReleaseProtector ansehen, um dieses Problem zu lösen (oder besser zu verstehen).
CFRelease nicht mehr Absturz auf NULL,
http://unsanity.org/archives/haxies/cfrelease_no_mo.php
Sie CFReleaseProtector.sit mit dem Kommandozeilen-Tool UNAR auspacken können (Teil des Unarchiver, siehe seine Google-Code-Download-Liste).
Immer noch Absturz (iOS 9). –
- 1. Warum würde TextToSpeech.getLanguage() * manchmal * null zurückgeben?
- 2. ARC und CFrelease?
- 3. Würde java.io.ByteArrayOutputStream.toByteArray() null zurückgeben?
- 4. Wann verwende ich CFRelease?
- 5. Warum würde eine Dependency-Property-Implementierung meine Anwendung abstürzen, wenn ich einen Standardwert bereitstelle?
- 6. Wann würde SqlCommand.ExecuteReader() null zurückgeben?
- 7. ASP.Net WebAPI OWIN: Warum würde Request.GetOwinContext() null zurückgeben?
- 8. Wann würde ShowDialog() null zurückgeben?
- 9. Warum würde das kompilieren?
- 10. Warum würde Collection.IMongo.Save() nicht zurückgeben?
- 11. Warum werden meine Threads nicht abstürzen und ein Speicherleck verursachen?
- 12. MKMapView _annotationContainer abstürzen
- 13. Wie würde ein Plattenspieler in CS: GO mit einem externen Programm abstürzen?
- 14. Wann würde eine Referenz Null initialisiert werden?
- 15. Warum endet strncpy nicht null?
- 16. Warum würde connect() EADDRNOTAVAIL geben?
- 17. Gulp BrowserSync abstürzen
- 18. wenn es hier läuft: CFRelease (Buch); dass EXC_BAD_ACCESS (code = EXC_l386_GPFLT)
- 19. Warum würde C# einen ungültigen Aufzählungswert zulassen?
- 20. Warum funktioniert String (null)?
- 21. Warum @ ($ null) ist $ false, aber @ ($ null, $ null) ist $ true?
- 22. Warum Benutzer null
- 23. Initialisieren von Diagrammobjekt in Abstürzen vba
- 24. Array verursacht Programm abstürzen C++
- 25. SQL Server-Agent-Jobs abstürzen
- 26. Wie Debuggen von zufälligen Abstürzen?
- 27. Importieren von XML-Abstürzen Excel
- 28. php artisan development server abstürzen
- 29. Warum Images.Media.insertImage null zurückgeben
- 30. Warum ist dateFormatter null?
Für mich sagt diese Antwort ziemlich viel: CFRelease stürzt ab, weil CF so funktioniert. free (NULL) stürzt nicht ab, weil der C-Standard dies sagt. delete NULL stürzt nicht ab, weil der C++ - Standard dies sagt. Es beantwortet meine Frage nicht. Ich frage, warum der CF-SDK-Designer bewusst beschlossen hat, dass seine öffentlichen APIs das Programm einfach zum Absturz bringen. –
Ohne einen CF-Designer direkt zu fragen (vorausgesetzt, sie können/werden Ihnen sagen, warum), spekulieren wir nur. Ich habe meine beste Vermutung in meiner Antwort dargelegt. –
Wenn Sie eine Frage stellen, die nur von der Person beantwortet werden kann, die diese API geschrieben hat, warum nach SO fragen? Der Sinn von SO besteht darin, Fragen zu stellen, die von der Gemeinschaft zu verantworten sind. – smorgan