Swift: дженерики и понижение в AnyObject

#generics #swift #nscache

#дженерики #swift #nscache

Вопрос:

У меня следующая ситуация: (просто скопируйте его на игровую площадку)

 import Cocoa

protocol UID {
    var uid: Int {get set}
}

class A : UID {
    var uid = 01
}

class manageUID<T: UID> {

    let cache = NSCache()

    func addUID(aObj: T) {
        cache.setObject(aObj, forKey:aObj.uid)
    }

    func deletedUID(aObj: T) {
        cache.removeObjectForKey(aObj.uid)
    }
}
 

Это приводит к ошибке «Не удалось найти перегрузку для setObject …»

Ну, я знаю, что проблема заключается в типе aObj в addUID, это непонятно для компилятора.

По пути можно было бы сказать

 func addUID(aObj: T) {
    cache.setObject(aObj as A, forKey:aObj.uid)
}
 

Но в этом случае a может полностью пропустить общую тему. Я пытаюсь понизить aObj до чего-то вроде AnyObject или NSObject, но это не сработало.

Есть идеи?

Было бы неплохо иметь общую версию кэша 🙂

Обновить:

Одним из решений является добавление атрибута @objc в протокол, поэтому протокол можно использовать только для классов, но это приводит к общему ограничению для протокола. Мне просто нравится локальное решение в классе manageUID.

Ответ №1:

Я нашел другое решение, основанное на ответе на мой вопрос здесь: https://devforums.apple.com/thread/233432

  protocol UID {
    var uid: Int {get set}
 }

 @class_protocol
 protocol ObjectUID : UID {

 }


 class manageUID<T: ObjectUID> {

    let cache = NSCache()

    func addUID(aObj: T) {
        cache.setObject(aObj, forKey:aObj.uid)
    }

    func deletedUID(aObj: T) {
        cache.removeObjectForKey(aObj.uid)
    }
 }
 

Комментарии:

1. Кстати. в некоторых случаях происходит сбой Xcode Beta2 с этим кодом, у вас есть то же самое?