2015-10-05 16 views
6

Tôi có một lớp sắp xếp theo thứ tự và deserializes với NSCoder/NSKeyedArchiverNSKeyedUnarchiver. Tôi có các bài kiểm tra đơn vị được thiết kế để kiểm tra việc xử lý các lỗi khác nhau của tôi bên trong định dạng tuần tự hóa của tôi (đó không phải là một bản lưu trữ đơn giản nhưng chứa các bản lưu trữ).NSKeyedUnarchiver unarchiveObjectWithData return nil

Tuy nhiên, vì tôi đã nâng cấp lên Swift 2/iOS 9, các thử nghiệm đang hiển thị một số hành vi bất thường. Trước đây, thử nghiệm cho các lưu trữ không hợp lệ đã thất bại khi deserializing một kho lưu trữ không hợp lệ đã ném một ngoại lệ Objective-C, như trạng thái tài liệu, đã phá vỡ chương trình khi Swift không thể bắt chúng. Điều này là tốt, tôi dự định sửa chữa thử nghiệm tại một số điểm trong tương lai.

Bây giờ, bài kiểm tra đã trôi qua. Khi cho ăn rác ngẫu nhiên hoặc xác định của tôi, thay vào đó tôi nhận được nil từ unarchiveObjectWithData thay vì ngoại lệ. Tôi đã kiểm tra các tài liệu cho phương pháp này và không có thay đổi hành vi nào được liệt kê.

Thành thật mà nói, tôi thấy thay đổi hành vi này là cực kỳ đáng ngờ vì không có đề cập đến bất cứ nơi nào hoặc tại sao thay đổi này xảy ra. Các bài kiểm tra đơn vị trước đây của tôi không thành công hiện tại không có lý do rõ ràng nào.

Vì vậy, đây có phải là hành vi được mong đợi mới (rằng nó trả về nil)? Nếu không, làm thế nào tôi có thể nhận được hành vi mong đợi thực tế (ngoại lệ Obj-C) thay vì nil cho một kho lưu trữ không hợp lệ?

Trả lời

3

Swift2/iOS9 giới thiệu không có giấy tờthrows phương pháp lớp trong NSKeyedUnarchiver:

extension NSKeyedUnarchiver { 
    @warn_unused_result 
    public class func unarchiveTopLevelObjectWithData(data: NSData) throws -> AnyObject? 
} 

Nhưng nó không có vẻ làm việc nếu các dữ liệu định dạng là hoàn toàn sai: Nó trả nil mà không có lỗi.

let dat = "test".dataUsingEncoding(NSUTF8StringEncoding)! 
try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(dat) // -> `nil` 

Lỗi chỉ được ném khi người bỏ lưu trữ tìm thấy một số thực thể không hợp lệ (ví dụ: tên lớp không xác định) trong khi giải mã. Tôi nghĩ rằng đó là một loại lỗi hoặc nó vô tình được phát hành với việc triển khai không đầy đủ.

Dù sao, nếu bạn muốn Objective-C ngoại lệ, bạn có thể chỉ xây dựng NSKeyedUnarchiver:

let dat = "test".dataUsingEncoding(NSUTF8StringEncoding)! 
let unarchiver = NSKeyedUnarchiver(forReadingWithData: dat) // -> throws Objective-C exception 

Nhưng, không có throws initializer ... chưa?

+0

Cảm ơn vì điều này. Tôi nghĩ rằng tôi sẽ xây dựng NSKeyedArchiver và xử lý thủ công rằng ObjC ngoại lệ cho bây giờ, do đó tôi không phải là trong bước này thực hiện một nửa un-tài liệu lạ. – Puppy