我试图制作一个协议,以便我可以打开 NSObject 值并使用时髦的帮助类来适当地处理它们。
基本上有两种情况:
无论我尝试多少演员阵容,以下代码都无法编译。
"无法转换类型' 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所以语法可能略有不同。)
答案 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)
}