2014-06-07 118 views
19

我在Swift中重寫了一個Objective-C類來感受這種語言。在Objective-C我的課包括以下方法:如何將NSDictionary轉換爲Swift Dictionary <String,NSObject>?

- (id) initWithCoder:(NSCoder *)aDecoder 
{ 
    return [self initWithActionName:[aDecoder decodeObjectOfClass:[NSString class] forKey:@"actionName"] 
          payload:[aDecoder decodeObjectOfClass:[NSDictionary class] forKey:@"payload"] 
          timestamp:[aDecoder decodeObjectOfClass:[NSDate class] forKey:@"timestamp"]]; 
} 

一些試驗和錯誤的編譯器後,我設法把它改寫這樣的:

convenience init(aDecoder: NSCoder) { 
    let actionName = aDecoder.decodeObjectOfClass(NSString.self, forKey: "actionName") as NSString 
    let payload = aDecoder.decodeObjectOfClass(NSDictionary.self, forKey: "payload") as NSDictionary 
    let timestamp = aDecoder.decodeObjectOfClass(NSDate.self, forKey: "timestamp") as NSDate 
    self.init(actionName: actionName, payload: payload, timestamp: timestamp) 
} 

然而,這仍然給我一個錯誤在最後一行:「找不到一個過載init接受所提供的參數」的init方法簽名爲

init(actionName: String, payload: Dictionary<String, NSObject>, timestamp: NSDate) 

所以我認爲問題是我想通過NSDictionary而不是Dictionary<String, NSObject>。我怎樣才能在這兩個不太相當的類型之間進行轉換?我是否應該使用NSDictionary來處理所有必須與其他Objective-C組件交互的代碼?

回答

14

將您的字典解碼爲Dictionary<String, NSObject>而不是NSDictionary

let payload = aDecoder.decodeObjectOfClass(NSDictionary.self, forKey: "payload") as! Dictionary<String, NSObject> 

由於您使用可可觸摸序列化和反序列化,他們序列化爲NSDictionary,但可以將其轉換爲斯威夫特Dictionary<,>,按照WWDC 2014 中介斯威夫特高級斯威夫特視頻。

您還可以解碼爲NSDictionary,然後明確地投對象,像這樣:

self.init(actionName: actionName, payload: payload as! Dictionary<String, NSObject>, timestamp: timestamp) 

基本上,你在玩在這裏與協方差/逆變。

1

你確定這是init的正確聲明嗎?參數順序與您在Objective-C代碼中調用的順序不同。

所以,如果你想精確重新實現,最後一次調用應該可能是self.init(actionName: actionName, timestamp: timestamp, payload: payload)。使用錯誤的參數順序調用初始化程序會導致您正在收到的錯誤消息。

+0

對不起,我感到困惑 - 因爲我正在重寫課程,所以我決定同時調整API。 Swift方法的參數順序是正確的,所以這不是問題。我已經編輯了這個問題來改變ObjC版本中參數的順序,所以沒有混淆。 – bdesham

相關問題