2015-12-29 32 views
5

Tôi có câu hỏi về xử lý ngoại lệ trong Swift. Tài liệu UIKit cho lớp UIStoryboard tuyên bố rằng instantiateViewControllerWithIdentifier (định danh: String) -> Hàm UIViewController sẽ ném một ngoại lệ nếu mã định danh là nil hoặc không tồn tại trong bảng phân cảnh. Tuy nhiên, nếu tôi sử dụng một/try/catch như sau, tôi nhận được một cảnh báo "Không có cuộc gọi để ném chức năng xảy ra trong biểu thức" thử "."xử lý ngoại lệ với swift

Đó chỉ là cảnh báo nên tôi đã nhận ra rằng đó là vấn đề quan trọng; nhưng khi tôi chạy đoạn mã sau và cố tình sử dụng một mã định danh không hợp lệ thì không có ngoại lệ nào bị bắt và một SIGABRT được tạo ra.

 let storyboard = UIStoryboard.init(name: "Main", bundle: nil) 
    do { 
     let controller = try storyboard.instantiateViewControllerWithIdentifier("SearchPopup") 

     // This code is only included for completeness... 
     controller.modalPresentationStyle = .Popover 
     if let secPopoverPresentationController = controller.popoverPresentationController { 
      secPopoverPresentationController.sourceView = self.view 
      secPopoverPresentationController.permittedArrowDirections = .Any 
      secPopoverPresentationController.barButtonItem = self.bSearchButton 
     } 
     self.presentViewController(controller, animated: true, completion: nil) 
     // End code included for completeness. 
    } 
    catch { 
     NSLog("Exception thrown instantiating view controller."); 
     return; 
    } 

Bạn phải làm gì/thử/nắm bắt các chức năng ném ngoại lệ như thế này?

Xin cảm ơn trước.

Bryan

+0

Xem phần này, Xử lý lỗi nhanh chóng: http://iosdevcenters.blogspot.in/2015/12/error-handling-in-swift-20.html –

+0

Cảm ơn bạn đã phản hồi nhanh. Điểm chính của câu hỏi của tôi đã bị mất trong tất cả các chi tiết. Các tài liệu nói rằng một ngoại lệ IS ném, nhưng XCode cảnh báo rằng không có ngoại lệ được ném - tại sao sự khác biệt? – Bryon

+0

Có, bạn nhận được RuntimeException, nhưng đối với chức năng tĩnh nó không phải nó. –

Trả lời

1

instantiateViewControllerWithIdentifier không phải là chức năng ném và bạn không thể xử lý bằng cách sử dụng ... try ... catch. Nếu bộ điều khiển chế độ xem không khả dụng trong bảng phân cảnh, bạn không thể làm gì. Đó là một sai lầm lập trình viên, người tạo ra nó, nên xử lý các vấn đề như vậy. Bạn không thể đổ lỗi cho thời gian chạy iOS cho loại lỗi như vậy.

+1

Cảm ơn Midhun và @ luk2302. Điều đó tạo nên ý nghĩa hoàn hảo cho các số nhận dạng được mã hóa cứng. Đối với định danh dữ liệu định hướng để lại một chút khoảng trống để tạo bằng chứng đạn ứng dụng nhưng hiểu hành vi này sẽ thúc đẩy kiểm tra phù hợp. Cảm ơn! – Bryon

0

Bạn không khôi phục từ ngoại lệ đó, ngoại lệ là RuntimeException.
Chỉ cần tự hỏi mình: "Tôi sẽ phản ứng như thế nào?" - nếu câu trả lời là "Tôi không biết" thì tại sao bạn thậm chí muốn bắt nó?

Lấy ví dụ về số nhận dạng không chính xác - bạn sẽ làm gì khi bắt lỗi ???

Bạn không thể khôi phục theo bất kỳ cách nào hợp lý. Nếu không thể tìm thấy số nhận dạng bạn chuyển vào, đó là điều bạn làm với nhà phát triển khi tạo ứng dụng. Đó là cái gì đó sẽ và nên được rõ ràng khi thử nghiệm các ứng dụng. Nếu bạn bằng cách nào đó bỏ lỡ ứng dụng của bạn sẽ bị lỗi trong Đánh giá của Apple hoặc trên thiết bị của khách hàng.

+0

Tôi phải không đồng ý. Nếu bạn thực tế nhận được số nhận dạng, thông qua yêu cầu http và bạn có hai phiên bản ứng dụng: NewVersion và OldVersion (vì bạn luôn có một số người dùng không cập nhật), bạn phải nắm bắt và phản ứng với lỗi trong OldVersion. Tôi đã có một số tình huống mà tôi sử dụng mã dự phòng để phản ứng, trong các phiên bản cũ, để mã chỉ các phiên bản mới có. Ví dụ, khối catch có thể kích hoạt một cảnh báo cho người dùng biết rằng anh ta cần cập nhật để kiểm tra nội dung mới, và điều đó chỉ làm xước bề mặt. – Uzaak

+0

@Uzaak sử dụng try-catch để phát hiện các bản cập nhật âm thanh cực kỳ tệ. Đó vẫn không phải là một trường hợp sử dụng hợp lệ để bắt các ngoại lệ như thế này. * Nếu * bạn nhận được mã định danh từ một nguồn bên ngoài, bạn nên * xác minh * nó trước, không chỉ * sử dụng * nó và phản ứng với các ngoại lệ kết quả. Âm thanh như một imho thiết kế xấu. – luk2302

+0

Tôi hoàn toàn đồng ý rằng nó cần được xác minh trước, nhưng Apple không cung cấp cho chúng tôi một cách để xác minh nó. Ban đầu, storyboard.instantiateViewControllerWithIdentifier có nghĩa là để trả về nil khi họ không tìm thấy một bộ điều khiển (như tài liệu đã nói lúc đó), đó là tốt. Nhưng nó sai lầm ném một ngoại lệ. Sau đó, họ sửa tài liệu (lol) và làm cho trường hợp ngoại lệ là trường hợp chung. Vì vậy, trừ khi có một cách không cố gắng để tìm ra nếu xem có tồn tại, tôi hiện đang dính vào điều này. Bạn có biết cách nào tốt hơn không? – Uzaak

3

Đây là một trường hợp cụ thể của vấn đề tổng quát hơn được thảo luận trong Catching NSException in Swift

Bản tóm tắt có vẻ là trường hợp ngoại lệ mà nhanh chóng và các ngoại lệ objc là khác nhau.

Trong trường hợp này, tài liệu nhanh chóng cho biết nó ném ngoại lệ, nhưng điều này không thể bị bắt; mà âm thanh như một lỗi tài liệu ít nhất.

Tôi không đồng ý với các câu trả lời khác ở đây rằng VC bị thiếu rõ ràng là lỗi lập trình viên. Nếu hành vi đã được ghi lại, người ta có thể mô tả một thiết kế mà mã phổ biến phản ứng khác nhau tùy thuộc vào việc VC có mặt hay không trong một trường hợp cụ thể | product | localization. Có thêm cấu hình bổ sung để đảm bảo rằng tải VC chỉ được cố gắng khi nó là hiện tại là một lời mời để lỗi trường hợp cạnh và muốn. c.f. cập nhật bất thường.