Tôi tự hỏi nếu đó là một thói quen tốt để sử dụng NSAssert tất cả các nơi? Lợi ích của việc đó là gì? Trong trường hợp nào là tốt nhất nên sử dụng nó?Xác nhận hoặc NSAssert tốt cho thực tế là gì?
Trả lời
Sử dụng rộng rãi NSAssert()
sẽ không biến ObjC thành Eiffel, nhưng nó vẫn là một thực hành khá tốt miễn là bạn ghi nhớ cách nó thực sự được triển khai và những gì nó đang thực hiện. Những điều cần ghi nhớ về NSAssert()
:
Xcode không tắt NSAssert()
trong Chế độ phát hành theo mặc định. Bạn phải nhớ thêm NS_BLOCK_ASSERTIONS
vào GCC_PREPROCESSOR_DEFINITIONS
trong xcconfig. (Bạn là using xcconfigs, phải không?) Một vấn đề phổ biến là để khẳng định không nil trong trường hợp nil lặng lẽ sẽ làm việc; điều này có thể có nghĩa là trường bị treo cho những thứ có thể khôi phục một cách duyên dáng. Điều này không liên quan đến macro NDEBUG
được sử dụng bởi assert()
và bạn phải nhớ xác định cả hai nếu mã của bạn bao gồm cả hai loại xác nhận.
Nếu bạn biên dịch NSAssert()
ở chế độ Phát hành, khi đó bạn sẽ không có chỉ báo nào xảy ra sự cố khi khách hàng gửi cho bạn nhật ký của họ. Cá nhân tôi quấn NSAssert()
trong các macro của riêng tôi luôn đăng nhập, ngay cả trong chế độ Phát hành.
NSAssert()
thường buộc logic trùng lặp. Hãy xem xét trường hợp thử nghiệm một con trỏ C++ cho NULL. Bạn sử dụng NSAssert()
, nhưng bạn vẫn còn cũng cần sử dụng thử nghiệm if()
đơn giản để tránh bị rơi trong trường. Loại mã trùng lặp này có thể trở thành nguồn gốc của các lỗi và tôi đã thấy mã không thành công do các xác nhận không còn hợp lệ nữa. (May mắn là điều này thường ở chế độ Debug!) Tôi đã tranh luận rất nhiều về cách tạo macro kết hợp xác nhận và if()
, nhưng khó thực hiện mà không bị mong manh hoặc làm cho mã khó hiểu.
Vì vấn đề cuối cùng, tôi thường đặt "NSAssert(NO, ...)
" trong mệnh đề else{}
thay vì thực hiện xác nhận ở đầu phương thức. Đây không phải là lý tưởng bởi vì nó di chuyển hợp đồng ra khỏi chữ ký phương pháp (do đó làm giảm lợi ích tài liệu của nó), nhưng nó là phương pháp hiệu quả nhất tôi đã tìm thấy trong thực tế.
Gỡ lỗi. Bất cứ khi nào bạn viết mã, bạn hầu như luôn đưa ra các giả định. Giả định về trạng thái của môi trường, giá trị của tham số, biến cục bộ và trường của bạn, v.v. Thông thường, những giả định này là sai (một đồng nghiệp cũ cho tôi một câu châm ngôn tốt, rằng "Giả định là mẹ của tất cả các fsckups") .
Các xác nhận tồn tại để xác thực giả định của bạn, tại thời điểm bạn tạo chúng. Bạn có phương thức
void foo(int x)
{
…
}
mà bạn biết và có tài liệu chỉ hoạt động cho x> 5? Khẳng định nó!
Các xác nhận trực tiếp cùng với thử nghiệm đơn vị và các phương pháp chính thức như một phần của thực hành mã hóa tốt. Trong khi một số có thể nghĩ rằng các bài kiểm tra đơn vị toàn diện đảm bảo các xác nhận là thừa, thì không phải như vậy. Ví dụ, bạn có thể có một giả định cho một phương thức mà, nói rằng, nhân viên luôn luôn trên 16 và dưới 100 tuổi - nhưng mã đó, vào lúc này, không yêu cầu điều này. Các bài kiểm tra đơn vị vượt qua các tham số đó sẽ thành công, nhưng sau đó khi bạn cần sử dụng giả định của mình, bạn sẽ có mã ở khắp mọi nơi đã vượt qua các bài kiểm tra, nhưng là sai.
Cảnh báo chính là các tác dụng phụ.Nếu bạn viết:
NSAssert([self.navigationController popViewControllerAnimated:YES]!=nil,@"Something fails");
popViewControllerAnimated:
sẽ được thực hiện trong phiên bản debug, nhưng không phải trong phiên bản phát hành mà dải NSAssert()
. Điều này có nghĩa là phiên bản phát hành của bạn sẽ hoạt động khác với phiên bản gỡ lỗi.
Vấn đề này sẽ biến mất nếu bạn là cẩn thận đủ:
UIViewController* vc = [self.navigationController popViewControllerAnimated:YES];
NSAssert(vc!=nil,@"Something fails");
+1 sâu sắc, mặc dù tôi không bao giờ gọi phương thức trong xác nhận. –
tôi khuyên bạn nên bài viết này
http://www.mikeash.com/pyblog/friday-qa-2013-05-03-proper-use-of-asserts.html
Và như bài báo nói nó thường là tốt để sử dụng một assert-cơ chế mà không phải là NSAssert. Ví dụ:
AGAssert thật tuyệt! Cảm ơn! – skywinder
- 1. SQLite: giới hạn thực tế là gì?
- 2. Thực tiễn tốt nhất cho mã xác nhận email
- 3. Cách xác nhận thông thường trong C là gì?
- 4. Hibernate: Event Listener hoặc Interceptor, những ưu điểm/nhược điểm trong thực tế là gì?
- 5. Hình ảnh xác thực vô hình tốt là gì?
- 6. Cà ri JavaScript: các ứng dụng thực tế là gì?
- 7. Hoặc là yêu cầu xác nhận
- 8. Ví dụ thực tế về ACID là gì?
- 9. Plugin xác thực xã hội tốt nhất và gần đây nhất cho Django là gì?
- 10. Lợi ích thực tế của ADO.NET Entity Framework là gì?
- 11. Phông chữ nhỏ tốt nhất cho nhật thực là gì?
- 12. Giá trị thời gian ms thực tế cho hằng số animTime của Android là gì?
- 13. Việc sử dụng biến số thực tế là gì?
- 14. Ứng dụng thực tế trong cuộc sống là gì?
- 15. Kiểm soát các xác nhận Java - Thực tiễn tốt nhất
- 16. Xác thực MVC3 Xác nhận thuộc tínhContext.memberName là null
- 17. kAudioSessionProperty_InputSources thực sự tốt cho điều gì?
- 18. Thư viện số lớn (hoặc được hỗ trợ tốt nhất) chuẩn (hoặc chính xác nhất) cho Lua là gì?
- 19. Cách tốt nhất để thực hiện xác thực đầu vào trong C++ bằng cin là gì?
- 20. Chiều cao và chiều rộng thực tế tối đa cho một ứng dụng Web là gì?
- 21. Xác thực thực tế dữ liệu JAXB với JAX-RS?
- 22. Điều gì là tốt hơn cho các nhà phát triển PHP - Unicode hoặc UTF-8?
- 23. Cách tốt nhất để thực hiện "hẹn giờ" là gì?
- 24. Plugin jquery để xác thực số điện thoại quốc tế
- 25. Vị trí bộ nhớ thực tế cho các biến tĩnh là gì?
- 26. Xác thực URL được quốc tế hóa - Đây có phải là sự cố không?
- 27. Thực thể HTTP chính xác là gì?
- 28. cách xác thực tên miền quốc tế
- 29. Đối số NULL có phải là một thực tế không tốt?
- 30. Cách tốt nhất để xác thực cho dịch vụ web
Tôi không hiểu tại sao bạn sẽ kết thúc bằng mã trùng lặp. Nếu xác nhận không thành công, mã của bạn không có nghĩa vụ lưu chính nó khỏi sự cố. Trong thực tế không có điểm, bởi vì một giả định bạn đã thực hiện đã bị phá vỡ, do đó, không có cách lành mạnh để lưu chương trình không bị rơi sau này, do trạng thái không nhất quán. –
Mã của bạn luôn có nghĩa vụ hoạt động tốt cho người dùng. Trong khi trong một số trường hợp, mối quan tâm của sự tham nhũng dữ liệu có nghĩa là việc đâm ngay lập tức là cách tiếp cận duy nhất. Nhưng trong nhiều trường hợp, điều này không đúng và khôi phục, cho thấy lỗi hoặc thậm chí không làm gì là thích hợp hơn trong Release vs crashing và để người dùng nhìn chằm chằm vào Springboard mà không có thông tin. Tôi đã nhìn thấy đủ xác nhận không chính xác trong mã sản xuất để rất cảnh giác với việc bị lỗi trước khi phát hành trong trường hợp không có tham nhũng dữ liệu có thể xảy ra. Gỡ lỗi là một tình huống hoàn toàn khác, và tôi ủng hộ sự cố nhanh chóng. –
Một ứng dụng tốt thừa nhận rằng nó có lỗi và tìm cách chứa chúng. Chỉ vì tôi có một lỗi nhỏ trong hệ thống trợ giúp không có nghĩa là toàn bộ trò chơi sẽ bị lỗi chỉ vì kỹ thuật "chương trình giờ đây không được xác định". Mỗi chương trình thực sự của bất kỳ kích thước liên quan đến khá nhiều hành vi không xác định. Đó là trách nhiệm của chúng tôi để giảm thiểu điều đó, nhưng cũng để sống trong đó và không sụp đổ mỗi khi một cái gì đó trông lạ. –