2016-07-26 19 views
1

我必須履行其在Objective-C像這樣定義的協議要求:如何在Swift中使用NSSet <Class>(導出爲Set <NSObject>)?

@protocol AProtocol <NSObject> 
+ (NSSet<Class> * _Nullable)someClasses; 
@end 

我想實現寫在斯威夫特的子類此協議。我想返回一組另一個對象的類。我想返回類的定義是這樣的:

class B: NSObject {} 

符合協議的類是這樣定義的:

class A: NSObject, AProtocol { 
    static func someClasses() -> Set<NSObject>? { 
     return [B.self] 
    } 
} 

爲什麼NSSet<Class>橋接Set<NSObject>,而不是設置?

此解決方案崩潰了,我該如何解決問題?

+0

有一個問題,我沒有看到'Set ?'如何返回協議上的'NSSet '返回類型。不應該是'Set '?此外,請包含AppDelegate類型的聲明。 –

+0

@PatrickGoley是的,我完全理解這種困惑,這讓我感到困惑。正如有人向我解釋的那樣:Class只是Objective-C中的一個對象,這就是爲什麼這樣橋接的原因。我認爲他們在其他情況下將它連接到AnyClass,但由於AnyClass不符合Hashable(這是Set的先決條件),這是不可能的。 Xcode生成這樣的協議接口。 AppDelegate是由Xcode生成的,我將它添加到原始文章中。 – Ben

+0

好的,問題本身已解決,我將編輯問題並添加答案,也許這對其他人有幫助。 – Ben

回答

0

NSSet<Class>橋接到Set<NSObject>因爲AnyClass不符合Hashable這對於SetValueType的前提條件。

它可與下面的擴展需要解決的NSObjectProtocol

extension NSObjectProtocol where Self: NSObject { 
    static var objcClass: NSObject { 
     return (self as AnyObject) as! NSObject 
    } 
} 

這將返回類鑄成NSObject的對象。因爲Swift的類型系統非常強大,所以在將類型直接轉換爲實例類型時,它不會編譯或發出警告,因此有必要首先將其轉換爲AnyObject。在Objective-C中,這很好,因爲Class也只是一個對象。由於NSObject是在Objective-C中實現的,擴展名僅用於NSObjectProtocol,所以這是保存使用(即使使用強制轉換)。 在NSObjectProtocol上實現擴展而不是在NSObject本身帶來了不會導出到Objective-C的積極效果。

相關問題