需要一个针对各种NSObject子类型的协议,不能返回NSObject'为了自我'

时间:2015-07-07 02:34:17

标签: swift class static protocols

我试图制作一个协议,以便我可以打开 NSObject 值并使用时髦的帮助类来适当地处理它们。

基本上有两种情况:

  1. I期待的类型有特殊处理(NSValue-> CGRect,NSNumber-> Int)
  2. I期待的类型已经是 NSObject 子类
  3. 无论我尝试多少演员阵容,以下代码都无法编译。

    "无法转换类型' NSObject的返回表达式?'预期的回报类型' Self?'"

    public protocol NSObjectWrappable {
        static func fromNSObject(value : NSObject?) -> Self?
    }
    
    extension NSObject : NSObjectWrappable {
        public static func fromNSObject(value: NSObject?) -> Self? {
            return value
        }
    }
    

    为了提供更大的图片,我基本上也得到了这个:

    extension CGRect : NSObjectWrappable {
        public static func fromNSObject(value : NSObject?) -> Self? {
            /// yatta yatta NSValue.CGRectValue()
        }
    }
    

    我的想法是,我可以对使用字典的Cocoa API使用一些通用的辅助方法。

    鉴于我显然不能按照我想要的方式去做,有什么方法可以使用最少的代码重复?理想情况下,我能够专注于泛型,但我认为这不可能。

    (这是Swift 2.0所以语法可能略有不同。)

2 个答案:

答案 0 :(得分:0)

这是我能提出的最短代码:

import Foundation

// The protocol defines no method
public protocol NSObjectWrappable {}

// The 'default' implementation
func fromNSObject<T : NSObject, U : NSObjectWrappable>(value : T?) -> U? {
    return value as? U
}


// Usage
extension NSNumber : NSObjectWrappable {}
extension NSDictionary : NSObjectWrappable {}

let aNumber = NSNumber(integer: 42) as NSObject
let unwrappedNumber : NSNumber? = fromNSObject(aNumber)

let aDict = NSDictionary(dictionaryLiteral: ("name", "John Smith"), ("age", "42")) as NSObject
let unwrappedDict : NSDictionary? = fromNSObject(aDict)

答案 1 :(得分:0)

我最终做的是轻微的代码重复。所以,我会打开我的问题,万一有更好的Swift方式用泛型来做这件事。我最终制作了3个类和3个辅助方法,并且由于类型推断,它并不是一个大问题。

public extension NSObject {
    func addObserver<Type : NSValueWrappable>(keyPath: String, handler: (kind : NSKeyValueChange, oldValue: Type?, newValue: Type?) -> Void) -> protocol<KeyValueObserver> {
        let opts : NSKeyValueObservingOptions = [NSKeyValueObservingOptions.Old, NSKeyValueObservingOptions.New]
        let observer = KeyValueStructObserver<Type>(object: self, keyPath: keyPath, options: opts)
        observer.changeHandler = handler
        observer.startObserving()
        return observer
    }

    func addObserver<Type : NSNumberWrappable>(keyPath: String, handler: (kind : NSKeyValueChange, oldValue: Type?, newValue: Type?) -> Void) -> protocol<KeyValueObserver> {
        let opts : NSKeyValueObservingOptions = [NSKeyValueObservingOptions.Old, NSKeyValueObservingOptions.New]
        let observer = KeyValueNumberObserver<Type>(object: self, keyPath: keyPath, options: opts)
        observer.changeHandler = handler
        observer.startObserving()
        return observer
    }

    func addObserver<Type : NSObject>(keyPath: String, handler: (kind : NSKeyValueChange, oldValue: Type?, newValue: Type?) -> Void) -> protocol<KeyValueObserver> {
        let opts : NSKeyValueObservingOptions = [NSKeyValueObservingOptions.Old, NSKeyValueObservingOptions.New]
        let observer = KeyValueObjectObserver<Type>(object: self, keyPath: keyPath, options: opts)
        observer.changeHandler = handler
        observer.startObserving()
        return observer
    }
}

清晰度示例用法:

_tabBar.addObserver("frame"){(_, oldValue: CGRect?, newValue: CGRect?) in
            let rect = newValue!
            print(rect)
        }