NSKeyedUnarchiver.decodeObject
sẽ gây ra sự cố/SIGABRT
nếu lớp gốc không xác định. Giải pháp duy nhất tôi đã thấy để bắt gặp vấn đề này bắt nguồn từ lịch sử ban đầu của Swift và được yêu cầu sử dụng Objective C (cũng có sẵn trước ngày triển khai Swift 2 của guard
, throws
, try
& catch
). Tôi có thể tìm ra con đường Objective C - nhưng tôi muốn hiểu một giải pháp Swift-only nếu có thể.Cách nhanh nhất để ngăn chặn sự cố NSKeyedUnarchiver.decodeObject?
Ví dụ: dữ liệu đã được mã hóa với NSPropertyListFormat.XMLFormat_v1_0
. Mã sau sẽ thất bại tại unarchiver.decodeObject()
nếu lớp dữ liệu được mã hóa không xác định.
//...
let dat = NSData(contentsOfURL: url)!
let unarchiver = NSKeyedUnarchiver(forReadingWithData: dat)
//it will crash after this if the class in the xml file is not known
if let newListCollection = (unarchiver.decodeObject()) as? List {
return newListCollection
} else {
return nil
}
//...
Tôi đang tìm kiếm một Swift 2 cách duy nhất để kiểm tra xem dữ liệu có giá trị trước khi thử .decodeObject
- kể từ .decodeObject
không có throws
- có nghĩa là try
-catch
dường như không phải là một lựa chọn trong Swift (phương pháp nếu không có throws
không thể được bọc AFAIK). Hoặc một cách khác để giải mã dữ liệu mà sẽ ném một lỗi tôi có thể bắt nếu giải mã không thành công. Tôi muốn người dùng có thể nhập tệp từ ổ iCloud hoặc Dropbox - do đó cần phải được xác thực hợp lệ. Tôi không thể giả định rằng dữ liệu được mã hóa là an toàn.
Phương thức NSKeyedUnarchiver
.unarchiveTopLevelObjectWithData
& .validateValue
cả hai đều có throws
. Có lẽ một số cách mà chúng có thể được sử dụng? Tôi không thể tìm ra cách để bắt đầu thực hiện validateValue
trong ngữ cảnh này. Đây có phải là một lộ trình có thể không? Hay tôi nên tìm đến một trong những phương pháp khác cho một giải pháp?
Hoặc có ai biết cách thay thế Swift 2 chỉ để giải quyết vấn đề này không? Tôi tin rằng chìa khóa mà tôi quan tâm có lẽ là $classname
- nhưng TBH Tôi đã vượt quá chiều sâu của mình để tìm cách thực hiện validateValue
- hoặc thậm chí cho dù đó có phải là con đường chính xác để kiên trì. Tôi có cảm giác rằng tôi đang thiếu một cái gì đó hiển nhiên.
EDIT: Đây là một giải pháp - nhờ của rintaro câu trả lời tuyệt vời (s) dưới đây
Câu trả lời đầu tiên giải quyết vấn đề này đối với tôi - ví dụ: thực hiện một đại biểu.
Còn bây giờ tuy nhiên tôi đã đi với một giải pháp xây dựng xung quanh phản ứng thay đổi nội dung thêm rintaro như sau:
//...
let dat = NSData(contentsOfURL: url)!
let unarchiver = NSKeyedUnarchiver(forReadingWithData: dat)
do {
let decodedDataObject = try unarchiver.decodeTopLevelObject()
if let newListCollection = decodedDataObject as? List {
return newListCollection
} else {
return nil
}
}
catch {
return nil
}
//...
Cảm ơn bạn rất nhiều. Đó là một câu trả lời tuyệt vời. – simons
Xem câu trả lời cập nhật của tôi. – rintaro
Cảm ơn bạn lần nữa. 'nếu thử unarchiver.decodeTopLevelObject()! = nil' làm việc cho tôi theo cách tôi đã thực hiện nó. Nếu nó không phải là 'nil' thì tôi tốt để đi. Tôi đã bỏ lỡ cái đó khi tìm kiếm các phương pháp ném. Câu trả lời ban đầu của bạn cũng phù hợp với tôi. – simons