Cập nhật: Từ Nhật ký thay đổi Swift 2.2 (phát hành ngày 21 tháng 3 năm 2016):
Các trình khởi tạo lớp được chỉ định được khai báo là khả dụng hoặc đang ném giờ có thể trả về nil hoặc tạo ra một lỗi tương ứng trước khi đối tượng được khởi tạo hoàn toàn.
Đối với Swift 2.1 trở về trước:
Theo tài liệu của Apple (và lỗi trình biên dịch của bạn), một lớp phải khởi tạo tất cả các thuộc tính được lưu trữ của nó trước khi trả về nil
từ trình khởi tạo khả dụng:
Tuy nhiên, đối với các lớp, bộ khởi tạo khả dụng chỉ có thể kích hoạt lỗi khởi tạo sau khi tất cả các thuộc tính được lưu trữ được giới thiệu bởi lớp đó đã được đặt thành giá trị ban đầu và bất kỳ ủy quyền trình khởi tạo nào đã diễn ra.
Lưu ý: Nó thực sự hoạt động tốt cho các cấu trúc và kiểu liệt kê, chỉ không phải các lớp.
Cách được đề xuất để xử lý các thuộc tính được lưu trữ không thể khởi tạo trước khi trình khởi tạo không thành công là khai báo chúng dưới dạng các tùy chọn không được bao bọc hoàn toàn.
Ví dụ từ tài liệu:
class Product {
let name: String!
init?(name: String) {
if name.isEmpty { return nil }
self.name = name
}
}
Trong ví dụ trên, thuộc tính name của lớp Sản phẩm được định nghĩa là có kiểu chuỗi tùy chọn không được bao bọc hoàn toàn (String!). Bởi vì nó thuộc loại tùy chọn, điều này có nghĩa là thuộc tính name có giá trị mặc định là nil trước khi nó được gán một giá trị cụ thể trong quá trình khởi tạo. Giá trị nil mặc định này đến lượt nó có nghĩa là tất cả các thuộc tính được giới thiệu bởi lớp Sản phẩm đều có giá trị ban đầu hợp lệ. Do đó, trình khởi tạo khả dụng cho Sản phẩm có thể gây ra lỗi khởi tạo khi bắt đầu trình khởi tạo nếu nó được chuyển qua một chuỗi trống, trước khi gán một giá trị cụ thể cho thuộc tính name trong trình khởi tạo.
Tuy nhiên, trong trường hợp của bạn, chỉ cần xác định userName
là a String!
không khắc phục được lỗi biên dịch vì bạn vẫn cần lo lắng về việc khởi tạo các thuộc tính trên lớp cơ sở của mình , NSObject
. May mắn thay, với userName
được định nghĩa là a String!
, bạn thực sự có thể gọi super.init()
trước khi bạn return nil
bắt đầu NSObject
lớp cơ sở của bạn và sửa lỗi biên dịch.
class User: NSObject {
let userName: String!
let isSuperUser: Bool = false
let someDetails: [String]?
init?(dictionary: NSDictionary) {
super.init()
if let value = dictionary["user_name"] as? String {
self.userName = value
}
else {
return nil
}
if let value: Bool = dictionary["super_user"] as? Bool {
self.isSuperUser = value
}
self.someDetails = dictionary["some_details"] as? Array
}
}
canSetCalculableProperties
tham số boolean cho phép trình khởi tạo của tôi tính toán các thuộc tính có thể hoặc không thể được tạo nhanh chóng. Ví dụ: nếu mộtdateCreated
khóa bị thiếu và tôi có thể đặt thuộc tính ngay lập tức vìcanSetCalculableProperties
tham số là true, thì tôi chỉ cần đặt nó thành ngày hiện tại.