2014-09-16 20 views
6

tôi có thể nhanh chóng lớp từ chuỗi trong ObjC.For Ví dụ, tôi đã xác định lớp DBCell mới thông qua subclassing UITableViewCell, và tôi nhanh chóng lớp từ tên với các mã:Làm thế nào để khởi tạo lớp và init từ chuỗi trong Swift?

DBCell *cell=[tableView dequeueReusableCellWithIdentifier:cellClassname]; 
    if (cell==nil) { 
     Class cellClass=NSClassFromString(cellClassname); 
     cell=[cellClass alloc]; 
     cell=[cell initWithStyle:cellStyle reuseIdentifier:cellClassname]; 
    } 

Bây giờ tôi cần chuyển mã để Swift, tôi đã xác định lại lớp DBCell trong Swift:

class DBCell: UITableViewCell { 
    var label:String? 
    var key:String? 
    var managedObject:NSManagedObject? 
    var delegate:AnyObject? 
    convenience override init(style: UITableViewCellStyle, reuseIdentifier: String!) { 
     self.init(style: style, reuseIdentifier: reuseIdentifier) 
     self.textLabel.font=UIFont.preferredFontForTextStyle(UIFontTextStyleCaption1) 
     self.backgroundColor=UIColor.blackColor() 
     self.textLabel.backgroundColor=UIColor.blackColor() 
    } 
    } 

Nhưng làm thế nào tôi có thể khởi tạo lớp và gọi hàm init thích hợp?

+0

Tôi cảm thấy rằng vấn đề của bạn là do kiến ​​trúc xấu, chủ yếu là thiếu đa hình được sử dụng đúng cách. Bạn có thể vui lòng hiển thị thêm mã obj-c ban đầu của bạn không? Sự khác biệt giữa các tế bào khác nhau là gì? – Sulthan

+0

@Sulthan Đây là một mẫu Cocoa khá phổ biến. Bạn có ý nghĩa gì bởi "đa hình được sử dụng đúng" trong trường hợp này? Vấn đề là các tên ô được lưu trữ trong bảng phân cảnh, khá thuận tiện và hữu ích. Câu hỏi đặt ra là làm thế nào để làm điều đó trong khi vẫn duy trì an toàn loại Swift (và đó là một câu hỏi hợp lý). –

Trả lời

15

Swift được nhập tĩnh hơn, điều này giúp an toàn hơn khi chạy. Ví dụ, nếu bất kỳ chuỗi nào sai, bạn sẽ gặp sự cố (hoặc tốt nhất không làm gì cả, điều này có thể tệ hơn là bị lỗi) và trình biên dịch không thể bắt được nó cho bạn.

OK, nhưng làm thế nào để bạn xử lý mẫu này? Cách tốt nhất, IMO, trong Swift là rõ ràng và tạo một ánh xạ.

let cellMapping = [ 
    "DBCell": DBCell.self, 
] 

if let cellClass = cellMapping[cellClassName] { 
    let cell = cellClass(style: cellStyle, reuseIdentifier: cellClassName) 
    // use cell 
} 

Bây giờ khi bạn cấu trúc lại và thay đổi tên của DBCell, nhưng bỏ lỡ chuỗi trong Storyboard, mọi thứ sẽ chỉ tiếp tục làm việc như mong đợi, chứ không phải đâm hoặc lặng lẽ không giống như nó sẽ ở ObjC.

Swift cũng thực sự thông minh về các ánh xạ này. Loại cellMapping ở trên là [String: DBCell.Type], vì vậy nếu bạn có một số đặc biệt init cho DBCell, nó sẽ có sẵn. Nhưng nếu từ điển của bạn trông giống như:

let cellMapping = [ 
    "DBCell": DBCell.self, 
    "OtherCell": UITableViewCell.self 
] 

thì loại là [String: UITableViewCell.Type]. Swift tự động tìm ra lớp cụ thể nhất bao gồm tất cả các giá trị. Nếu bạn đã thêm một loại vào danh sách này mà không có một số phương pháp bạn thực sự sử dụng, Swift có thể nắm bắt điều đó tại thời gian biên dịch. Và nếu bạn đã thực hiện một sai lầm và thêm một cái gì đó mà không phải là ngay cả một tế bào xem bảng:

let cellMapping = [ 
    "DBCell": DBCell.self, 
    "OtherCell": UITableViewCell.self, 
    "BadCell": UICollectionViewCell.self 
] 

sau đó Swift sẽ cung cấp cho bạn một thời gian biên dịch cảnh báo rằng bạn đã tạo một AnyObject. Đó là thực sự tốt đẹp trong việc viết mã an toàn nhưng linh hoạt, tất cả cho chi phí của một từ điển.

+0

Cảm ơn, nó đã hoạt động! – user1190178

+0

Có cách nào để tạo một ánh xạ ô sẽ làm cho công việc này với các loại khác nhau không? –

+0

Tôi không hiểu câu hỏi. Bạn nên hỏi một câu hỏi SO mới với các chi tiết về vấn đề cụ thể của bạn. –

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