Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 需要针对各种NSObject子类型的协议,can';t返回';NSObject';对于';自我';_Swift_Class_Static_Protocols - Fatal编程技术网

Swift 需要针对各种NSObject子类型的协议,can';t返回';NSObject';对于';自我';

Swift 需要针对各种NSObject子类型的协议,can';t返回';NSObject';对于';自我';,swift,class,static,protocols,Swift,Class,Static,Protocols,我正在尝试制定一个协议,以便可以展开NSObject值,并使用时髦的助手类适当地处理它们 基本上有两种情况: 我期望的类型具有特殊处理(NSValue->CGRect,NSNumber->Int) 我期望的类型已经是一个NSObject子类 无论我尝试了多少次强制转换,下面的代码都不会编译 “无法将类型为'NSObject'的返回表达式转换为预期的返回类型'Self'” 从更大的角度来看,我还得到了以下基本信息: extension CGRect : NSObjectWrappable {

我正在尝试制定一个协议,以便可以展开NSObject值,并使用时髦的助手类适当地处理它们

基本上有两种情况:

  • 我期望的类型具有特殊处理(NSValue->CGRect,NSNumber->Int)
  • 我期望的类型已经是一个NSObject子类
  • 无论我尝试了多少次强制转换,下面的代码都不会编译

    “无法将类型为'NSObject'的返回表达式转换为预期的返回类型'Self'”

    从更大的角度来看,我还得到了以下基本信息:

    extension CGRect : NSObjectWrappable {
        public static func fromNSObject(value : NSObject?) -> Self? {
            /// yatta yatta NSValue.CGRectValue()
        }
    }
    
    我的想法是,我可能能够对使用字典的Cocoa API使用一些通用帮助器方法

    考虑到我显然不能按照我所希望的方式来做,什么样的方式可以在最少的代码重复情况下工作?理想情况下,我能够专门化泛型,但我认为这是不可能的


    (这是Swift 2.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)
    
    <代码>导入基础 //协议没有定义任何方法 公共协议NSObjectWrappable{} //“默认”实现 func fromNSObject(值:T?->U?{ 返回值为?U } //用法 扩展NSNumber:NSObjectWrappable{} 扩展NSDictionary:NSObjectWrappable{} 让aNumber=NSNumber(整数:42)作为NSObject 让我们打开包装编号:NSNumber?=fromNSObject(一个成员) 让aDict=NSDictionary(dictionaryTerral:(“name”,“John Smith”),(“age”,“42”)作为NSObject 让我们展开:NSDictionary?=fromNSObject(aDict)
    我最后做的是轻微的代码重复。所以,我将保留我的问题,以防有更好的快速方法来处理泛型。我最终创建了3个类和3个helper方法,由于类型推断,这并不是什么大问题

    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
        }
    }
    

    我可以问一下你为什么声称需要一个通用的?为什么不接收该值并查看其类型并相应地采取行动呢?我想看看我能得到一个类型安全的KVO API有多灵活。这是一个很好的快速学习项目。也许我遗漏了一些东西,但你如何将原语扩展到这个?我所追求的是从NSValue中安全地获取结构类型,从NSNumber中获取原始数字,并且只返回输入,而无需特殊处理。
    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)
            }