Có một lý do tại sao CFRelease không kiểm tra NULL? Không phải là nó không thể chấp nhận được khi [nil release]; miễn phí (NULL); xóa NULL; tất cả các công việc hoàn toàn tốt đẹp?Tại sao tai nạn CFRelease (NULL)?
Trả lời
Mã nguồn cho CoreFoundation có sẵn công khai. Cụ thể, đối Snow Leopard mã để CFRelease là trong http://www.opensource.apple.com/source/CF/CF-550/CFRuntime.c
Dưới đây là những gì các phần có liên quan trông giống như:
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
}
này không trả lời câu hỏi của bạn về động cơ thiết kế, nhưng bạn cũng được hỏi tại sao không CFRelease không kiểm tra NULL. Nó kiểm tra và không thành công khi NULL được chuyển thành tham số.
Niềm tin cá nhân của tôi tương tự như của Quinn- rằng các nhà thiết kế CF cảm thấy đó là lỗi lập trình để chuyển sang NULL.
Tất cả các chức năng này là một phần của các API khác nhau mà theo quy ước khác nhau liên quan đến xử lý NULL
:
CFRelease
là một phần của SDK CoreFoundation C, mà không chấp nhậnNULL
tài liệu tham khảo như các đối số theo mặc định.[nil release]
sử dụng Objective-C (cho phép dereferences củanil
)free(NULL)
là một phần của thư viện C (libc
) mà cho phépNULL
luậndelete NULL
là một phần của ++ thư viện C (libc++
) mà cho phépNULL
luận
Tôi đoán là CoreFoundation
Nhà văn SDK đã quyết định nhất quán hơn với phần còn lại của SDK thay vì có chức năng tương tự trong các SDK khác.
Điểm tốt, dường như nó không có ý nghĩa gì nhiều trong nháy mắt đầu tiên. Tất nhiên, các behavior is properly documented, nhưng nó sẽ được tốt đẹp nếu nó có thể xử lý NULL
một cách duyên dáng. Lưu ý rằng CFRetain
và CFMakeCollectable
(mới trong 10.4, GC được bật trong 10.5) thể hiện cùng một hành vi. Tôi không thuộc về tất cả các động lực để thiết kế nó theo cách đó, nhưng sự nhấn mạnh có lẽ là nhiều hơn về tính nhất quán nội bộ với phần còn lại của khung CoreFoundation.
Rất khó hiểu/không thể biết được lý do tại sao CF được thiết kế theo cách đó trừ khi bạn có thể hỏi một trong các nhà thiết kế. Đoán tốt nhất của tôi là các nhà thiết kế đã quyết định rằng việc chuyển giao NULL cho các chức năng quản lý bộ nhớ là (phải là?) Một lỗi lập trình. Người ta có thể tranh luận rằng việc gây ra sự cố trên NULL là một hành vi "không nhanh" mong muốn, vì các lỗi xảy ra gần như ngay lập tức dễ dàng theo dõi hơn các lỗi mà không làm gì thay vì những gì bạn mong đợi. Cá nhân, tôi thích cách tiếp cận không-không-trên-null, nhưng tôi đoán đó là cuộc sống ...
Do API không thể/sẽ không thay đổi, bạn có thể kiểm tra NULL hoặc khắc phục sự cố trường hợp. Một tùy chọn có thể là định nghĩa một hàm nội tuyến hoặc macro chỉ gọi CFRelease cho các tham chiếu không NULL. Trong bất kỳ trường hợp nào, có thể tốt nhất là phải rõ ràng trong mã của bạn để tránh nhầm lẫn xuống đường.
Hãy xem xét rằng Quartz CGImageRelease và similars chấp nhận NULL: "Hàm này tương đương với CFRelease, ngoại trừ việc nó không gây ra lỗi nếu tham số hình ảnh là NULL." – IlDan
Phải, nó sẽ tốt đẹp, nhưng đó là trong CoreGraphics, không phải Core Foundation. Nếu CFRelease và bạn bè bị thay đổi thành ** not ** crash khi trao NULL, nó có thể gây ra kết quả không mong muốn trong mã hiện tại (mặc dù hy vọng không ai cố ý gây ra sự cố theo cách này) và gây nhầm lẫn cho các lập trình viên CoreFoundation. Mặc dù vậy, tôi có xu hướng đồng ý với bạn. –
Bạn có thể xem mã nguồn của CFReleaseProtector để xử lý (hoặc hiểu rõ hơn) vấn đề này.
CFRelease không sụp đổ trên NULL,
http://unsanity.org/archives/haxies/cfrelease_no_mo.php
Bạn có thể giải nén CFReleaseProtector.sit với công cụ unar dòng lệnh (một phần của The Unarchiver, xem danh sách mã tải Google của nó).
Vẫn gặp sự cố (iOS 9). –
- 1. Tai nạn iOS WebTryThreadLock
- 2. Tai nạn CoreTelephony
- 3. Tai nạn UIWebView EXC_BAD_ACCESS
- 4. Tai nạn hủy diệt
- 5. Tai nạn mẫu OpenNI UserTracker.java
- 6. NSDictionary allKeys tai nạn - Không thể hiểu được hoàn cảnh Báo cáo tai nạn
- 7. UIWebView tai nạn và tôi không có ý tưởng tại sao
- 8. Tai nạn dịch vụ gỡ lỗi
- 9. imagick tai nạn với PHP 5.3
- 10. SIGNAL 11 SIGSEGV tai nạn Android
- 11. MEDIA_ERR_SRC_NOT_SUPPORTED tai nạn âm thanh html5
- 12. CALayer renderInContext: gây tai nạn chưa biết
- 13. Tai nạn hiệu ứng thẻ cào ios
- 14. Tai nạn PhantomJS - Mã thoát 126
- 15. Tai nạn ứng dụng MFMailComposeViewController trong ipad
- 16. Tạo vụ tai nạn .NET tự động
- 17. Chương trình Ví dụ SharpSVN Tai nạn
- 18. tai nạn vim với plugin AutoComplPop
- 19. vụ tai nạn điện thoại trên "resume"
- 20. Ma trận gây ra tai nạn
- 21. Bắt đầu dưới cùng của vụ tai nạn
- 22. Bộ điều hợp dữ liệu đổ đầy tai nạn
- 23. Android: Tai nạn khi xoay, ngang theo chiều dọc
- 24. Tại sao Activity.getPackageManager() trả về null
- 25. Tai nạn tế bào nguyên mẫu UISearchDisplayController và UITableView
- 26. Truy cập self.view.frame trong loadView gây tai nạn EXC_BAD_ACCESS
- 27. Tai nạn ứng dụng thống nhất trên cảnh đầu tiên
- 28. Rỗng "phát hành" ASSERT macro tai nạn chương trình?
- 29. Tai nạn lạ khi gỡ lỗi đối tượng COM destructor
- 30. Tai nạn ứng dụng iPhone (Chỉ dành cho iOS4)
Với tôi, câu trả lời này khá nhiều nói: CFRelease bị treo vì CF hoạt động theo cách đó. miễn phí (NULL) không sụp đổ vì tiêu chuẩn C nói như vậy. xóa NULL không sụp đổ vì C + + tiêu chuẩn nói như vậy. Nó không trả lời câu hỏi của tôi. Tôi hỏi tại sao nhà thiết kế SDK CF cố tình quyết định chỉ cho phép các API công khai của họ phá vỡ chương trình. –
Nếu không yêu cầu một nhà thiết kế CF trực tiếp (giả sử họ có thể/sẽ cho bạn biết lý do tại sao) chúng tôi chỉ đang suy đoán. Tôi đã đưa ra dự đoán tốt nhất của tôi trong câu trả lời của tôi. –
Nếu bạn đang đặt câu hỏi chỉ có thể được trả lời bởi người đã viết API này, tại sao yêu cầu SO? Điểm của SO là đặt các câu hỏi mà cộng đồng chịu trách nhiệm. – smorgan