2015-11-05 73 views
0

我有一個充當BLL的類,封裝了一個服務協議。該服務協議提供了一個SerializableObjectProtocol對象的列表。例如,我有User,它實現SerializedObjectProtocol快速鑄造泛型數組導致致命錯誤

以下功能蒙上了SerializedObjectProtol陣列爲User

public func Get() -> [T] 
{ 
    let result = self._service.Get() 

    return result as! [T] 
} 

其結果是,我收到以下錯誤:

array element cannot be bridged to Objective-C 

我知道該代碼是容易出錯的,因爲如果對象不是T,則不會發生向下投射。因此,這裏是我可以驗證:在約束

  • 噸至實施SerializedObjectProtol即

    class DataLayer<T:SerializableObjectProtocol> 
    
  • T是類型用戶。 result是一個用戶數組。即[User]

  • 我可以解決這個問題,但我必須手動投射每個項目。其結果是,這工作完全正常:

    var returnArray = [T]() 
    
    for item in result 
    { 
        returnArray.append(item as! T) 
    } 
    
    return returnArray; 
    

我剛拿起斯威夫特的項目,它的經驗,所以我已經限制。因此,我出去看看我正在嘗試的是什麼(將數組[S]轉換爲[T])。看起來如果數組是[Any]這是可能的。

這是在Swift中的有效操作嗎?或者這種方式不可能。

回答

3

通常是不可能直接的Any它所包含的類型的陣列之間鑄造,因爲Any的存儲器中存有完全不同表示:sizeof(Any)不等於sizeof(User)!一個數組可能有320個字節的長度,但10個User只需要80個字節,這同樣適用於任何協議。結論:您需要投射每一件物品。

也許不喜歡這樣:

return results.map{ $0 as! User } 

,或者如果你不知道每一個項目是否是User,你只能返回User就像這樣:

return results.flatMap{ $0 as? User } 

如果您仍然存在問題,請發佈一些仍然會產生錯誤的最小代碼,但如果沒有實際的代碼,很難理解代碼的外觀如何?

+0

這是goo d知道。非常感謝你!我看過有關[Any] - > [T]的文章,但互聯網並不總是學習適當約定的最佳場所。 –

+0

注意:混合和匹配這樣的鑄造通常不是一個好主意。在這種情況下,絕對確定該對象是用戶。該服務設置爲返回需要序列化的服務的SerializableObjectProtocol,例如WebService,可以從一個對象中提取字段/值的字典。在這一點上,如果一個對象不是User,那麼在邏輯鏈的某個地方就會發生一個錯誤。像這樣有選擇性地將對象集合處理爲實體類,並打破協議所鼓勵的鬆散耦合。 –

+0

@SergueiFedorov協議何時才能成爲用戶?一般來說,我認爲如果你需要在你的(純粹的)Swift代碼中進行轉換,那麼你做錯了什麼,在用純Swift編程時(沒有ObjC,沒有JSON等)我根本沒有用過它們。 – Kametrixom