2016-07-26 5 views
1

я должен выполнить требование в протокол, который определен в Objective-C, как это:Как использовать NSSet <Class> в Swift (экспортируется как Set <NSObject>)?

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

Я хочу реализовать этот протокол в подклассе написанном в Swift. Я хочу вернуть набор классов другого объекта. Класс я хочу вернуться, определяется следующим образом:

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, которая является необходимым условием для ValueType из Set.

Она может быть решена с помощью следующего расширения для NSObjectProtocol:

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

Это возвращает класс объекта отлитого в NSObject. Необходимо сначала перенести его на AnyObject, потому что система типов Swift настолько сильна, что не будет компилировать или давать предупреждение при прямом литье типа в тип экземпляра. В Objective-C это прекрасно, потому что Class также является просто объектом. Так как NSObject реализован в Objective-C, а расширение - только для NSObjectProtocol, это экономит на использовании (даже с применением силы). Внедрение расширения на NSObjectProtocol и не на NSObject само по себе приносит положительный эффект, что он не экспортируется в Objective-C.