2016-04-07 3 views
1

Я пытаюсь расширить класс UIKit (который я не могу редактировать нормально), создав новую функцию и новую переменную типа Function, которая будет использовать ObjC Runtime, чтобы заставить ее выглядеть & чувствуют себя как сохраненное свойство.Динамически определенный тип функции vars

extension UITextField { 

    private struct DynamicallyDefinedVars { 
     static var oneVar = "oneVar" 
    } 

    var oneVar: ((String?)->Bool)? { 
     get{ 
      return objc_getAssociatedObject(self, &DynamicallyDefinedVars.oneVar) as? (String?)->Bool 
     } 
     set{ 
      if let newValue: AnyObject = newValue { 
       objc_setAssociatedObject(self, &DynamicallyDefinedVars.oneVar, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 
      } 
     } 
    } 

    func callTheVarFunc() -> Bool { 
     if let oneVar = oneVar { 
      return oneVar("Foo") 
     } 

     return true 
    } 
} 

То, что я надеюсь достичь:

var foo: UITextField 

foo.oneVar = { (bar: String?) -> Bool in 
    return true 
} 

if foo.callTheVarFunc { 
    doSomething 
} 

Но я получаю следующее сообщение об ошибке:

Cannot convert value of type '((String?) -> Bool)?' to specified type 'AnyObject?' 

Это будет работать хорошо, если oneVar набралось что-то вроде строки или массива сортирует, но я вижу, что типы функций не включены в AnyObject, что дает мне проблемы при попытке objc_setAssociatedObject. Любые мысли о том, как я могу получить желаемое поведение (через расширения, без подкласса)? Каждый экземпляр должен иметь другое значение oneVar, которое будет использоваться с функцией callTheVarFunc.

ответ

1

Я только что видел эту проблему, в Swift закрытия не может быть преобразован в AnyObject так что вы можете обойти эту досадную вещь создать пользовательский класс:

extension UITextField { 

    class CustomClosure { 
     var closure: ((String?)->Bool)? 

     init(_ closure: ((String?)->Bool)?) { 
      self.closure = closure 
     } 
    } 

    private struct DynamicallyDefinedVars { 
     static var oneVar = "oneVar" 
    } 

    var oneVar: ((String?)->Bool)? { 
     get{ 
      if let cl = objc_getAssociatedObject(self, &DynamicallyDefinedVars.oneVar) as? CustomClosure { 
      return cl.closure 
      } 
     return nil 
     } 
     set{ 
      objc_setAssociatedObject(self, &DynamicallyDefinedVars.oneVar,CustomClosure(newValue), .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 
     } 
    } 

    func callTheVarFunc() -> Bool { 
     if let oneVar = oneVar { 
      return oneVar("Foo") 
     } 

     return true 
    } 
} 
Смежные вопросы