2015-01-29 10 views
9

Nel tentativo di utilizzare questo metodo: class_addMethod() che in Obj-C viene utilizzato in questo modo:chiusura Swift come ANYOBJECT

class_addMethod([self class], @selector(eventHandler), imp_implementationWithBlock(handler), "[email protected]:"); 

E Im usarlo come questo in Swift:

class_addMethod(NSClassFromString("UIBarButtonItem"), "handler", imp_implementationWithBlock(handler), "[email protected]:") 

E ' un'estensione per UIBarButtonItem come potresti aver capito.

imp_implementationWithBlock prende un parametro di tipo AnyObject!

Come posso lanciare ()->() in AnyObject?

Ho cercato di lanciare in questo modo: handler as AnyObject ma mi dà un errore che dice: ()->() does not conform to protocol 'AnyObject'

+0

Hai provato usando 'reinterpretCast()'? – Romain

risposta

9

Come posso lanciare ()->() in AnyObject?

Attenzione: Questa risposta include funzionalità non documentata e non sicuri a Swift. Dubito che passi la recensione di AppStore.

let f:()->() = { 
    println("test") 
} 

let imp = imp_implementationWithBlock(
    unsafeBitCast(
     f as @objc_block()->(), 
     AnyObject.self 
    ) 
) 
+0

Qual è 'f' ? È la chiusura? – Arbitur

+0

Oops, ha modificato la risposta. – rintaro

+0

Quindi, perché Apple ha un 'func imp_implementationWithBlock (_ block: AnyObject!) -> IMP' nel riferimento lib se hai bisogno di quel codice che hai postato? Bug? –

4

Non è possibile. Puoi lanciarlo solo su Any.

  • AnyObject può rappresentare un'istanza di qualsiasi tipo di classe.
  • Any può rappresentare un'istanza di qualsiasi tipo, inclusi i tipi di funzione.

Apple Inc. "The Swift Programming Language." IBooks. https://itun.es/de/jEUH0.l

+0

Ma c'è un altro modo per farlo in qualche modo? – Arbitur

+0

Hai provato a passare 'Selector (" gestore ")'? Puoi mostrare la firma di 'imp_implementationWithBlock'? –

+0

L'errore è neanche la parte di selezione, il suo l'imp_implementationWithBlock() che causa confuson – Arbitur

2

Questo ha funzionato per me:

let myBlock: @objc_block() -> Void = { 
} 
var mf : AnyObject = unsafeBitCast(myBlock, AnyObject.self) 
8

si potrebbe scrivere un involucro, poi passarlo alla funzione

class ObjectWrapper<T> { 
    let value :T 
    init(value:T) { 
     self.value = value 
    } 
} 

let action = ObjectWarpper(value: {()->() in  
    // something 
}) 
4

In Swift 2, è necessario utilizzare @convention invece di @objc_block . Vedere Type Attribute

func swizzle(type: AnyClass, original: Selector, methodType: MethodType, block:() -> Void) { 
    let originalMethod = method(type, original: original, methodType: methodType) 

    let castedBlock: AnyObject = unsafeBitCast(block as @convention(block)() -> Void, AnyObject.self) 

    let swizzledImplementation = imp_implementationWithBlock(castedBlock) 
    // More code goes here 
} 
0

Usa Any oggetto (Il protocollo al quale tutti i tipi implicitamente conforme)

let aBlock: (view: View) -> Void = { view in /**/ } 

let block:Any? = aBlock