2016-03-31 16 views
11

Trong Mục tiêu-C, NSSetUncaughtExceptionHandler có thể đăng ký một số chức năng để thực hiện một số lần ghi nhật ký cuối cùng về ngoại lệ.Cách bắt gặp sự cố Swift và thực hiện việc ghi nhật ký

Điều này không bắt được sự cố nào xảy ra với Swift.

Có thể làm điều gì đó như thế này ở cấp độ toàn cầu trong Swift không? Ví dụ. làm một số đăng nhập nếu một vụ tai nạn xảy ra trong mã Swift, như buộc mở một nil tùy chọn.

Cụ thể, tôi đang thực hiện một tiện ích để ghi lưu lượng mạng trong ứng dụng và tôi muốn xóa dữ liệu trong bộ nhớ của mình ra đĩa nếu xảy ra sự cố.

+0

Tôi nghĩ có lẽ Apple đã không làm việc cho điều này giống như Refactor. – Lumialxk

Trả lời

1

Có nhiều khía cạnh để câu hỏi của bạn, hãy để tôi cố gắng trả lời họ:

  1. NSSetUncaughtExceptionHandler chỉ bắt ngoại lệ còn tự do mà chỉ là một nhóm nhỏ các tai nạn có thể.
  2. Exceptions trong Objective-C được xác định là gây tử vong và nó không được khuyến khích để bắt họ và thậm chí không nên chạy bất kỳ mã an toàn phi async, trong đó bao gồm bất kỳ Objective-C và mã Swift
  3. Để bắt tai nạn bạn cần thiết lập trình xử lý tín hiệu và sau đó chỉ chạy mã async-an toàn tại thời điểm xảy ra sự cố, đó chỉ là một tập hợp con nhỏ C. Đặc biệt bạn không thể cấp phát bộ nhớ mới tại thời điểm xảy ra sự cố.
  4. Hãy nhớ rằng, khi ứng dụng của bạn gặp sự cố, mã không ổn định và đối tượng hoặc tham chiếu biến có thể trỏ đến điều gì đó hoàn toàn bất ngờ. Vì vậy, bạn thực sự không nên làm bất cứ điều gì tại thời điểm tai nạn ở tất cả.
  5. Cách nguồn mở tốt nhất để làm việc với sự cố là sử dụng PLCrashReporter, cũng cung cấp phương thức gọi mã tại thời điểm gặp sự cố. Nhưng một lần nữa, điều này phải là an toàn không đồng bộ.

Để kịch bản cụ thể của bạn: bạn không nên làm điều đó và không cố gắng. Điều này có thể khiến dữ liệu người dùng bị hỏng hoặc mất nhiều dữ liệu hơn. Ứng dụng gặp sự cố nghiêm trọng với các vấn đề nghiêm trọng, thay vì khắc phục sự cố.

-1
NSSetUncaughtExceptionHandler(&HandleException); 
signal(SIGABRT, SignalHandler); 
signal(SIGILL, SignalHandler); 
signal(SIGSEGV, SignalHandler); 
signal(SIGFPE, SignalHandler); 
signal(SIGBUS, SignalHandler); 
signal(SIGPIPE, SignalHandler); 

Điều này sẽ có hiệu quả trong hầu hết các trường hợp. Nhưng tôi cũng đang cố gắng tìm cách để bắt tất cả các sự cố. Vâng, nếu bạn comd + bấm vào những tín hiệu để xem tài liệu, bạn sẽ tìm thấy có hơn 20 loại tín hiệu, những gì tôi đã làm là tín hiệu (,) tất cả hầu hết tất cả các loại tín hiệu. Điều đó có vẻ hoạt động, nhưng có lẽ vẫn còn một số vụ tai nạn không thể thu thập.

5

NSSetUncaughtExceptionHandler chỉ hoạt động với NSExceptions. Xem câu trả lời this SO để có giải thích tuyệt vời.

Để bắt các lỗi thời gian chạy Swift, hãy thực hiện trình xử lý tín hiệu cho SIGTRAP. Theo như tôi biết, mã Swift sẽ chấm dứt chương trình với loại trừ là SIGTRAP nếu phát hiện một điều kiện bất ngờ lúc chạy. Chỉ có SIGTRAP là hữu ích để bắt lỗi Swift, phần còn lại như SIGSEGV, SIGBUS, SIGILL không hoạt động. Tôi tìm thấy thông tin này trong liên kết this apple.

Nếu mã của bạn là hỗn hợp cả Objective-C và Swift, thì hãy triển khai cả hai NSSetUncaughtExceptionHandler và trình xử lý tín hiệu để xử lý sự cố.

Để hiểu và triển khai Xử lý tín hiệu, hãy tham khảo liên kết this.

Hy vọng điều này sẽ hữu ích.

+2

Tôi thêm một bộ xử lý tín hiệu cho hầu hết các tín hiệu ('SIGTRAP' được bao gồm), tuy nhiên nó không xử lý" lỗi nghiêm trọng: bất ngờ tìm thấy nil trong khi mở một giá trị Tùy chọn ". Tôi cũng đã thêm một trình xử lý ngoại lệ với 'NSSetUncaughtExceptionHandler()' ... –

Các vấn đề liên quan