im essayant d'utiliser cette méthode: et je l'utilise comme ceci à Swift: p> Il s'agit d'une extension pour Comment puis-je lancer J'ai essayé de la jeter comme ceci: class_addmethod () code> qui dans obj-c est utilisé comme suit:
uibarbuttonitem de code> comme vous l'avez peut-être affiché. p>
imp_implementationwithblock code> prend un paramètre de type
anyobject! code> p>
() -> () code> dans code> code> p>
gestionnaire comme anyobject code> mais cela me donne une erreur disant:
() -> () ne se conforme pas au protocole 'NyObject' code> p> p>
7 Réponses :
Vous ne pouvez pas. Vous ne pouvez le mettre que sur Apple Inc. "Le langage de programmation rapide". Ibooks. https://itun.es/de/jeuh0.l p> tout code>. p>
anyobject code> peut représenter une instance de n'importe quel type de classe. LI>
tout code> peut représenter une instance de n'importe quel type, y compris les types de fonctions. LI>
ul>
Mais y a-t-il une autre façon de le faire de quelque manière que ce soit?
Avez-vous essayé de passer sélecteur ("gestionnaire") code>? Pouvez-vous montrer la signature de
imp_implementatationwithblock code>?
L'erreur n'est pas la partie sélecteur, c'est l'IMP_IMPLEVEMENTATIONAlue () qui provoque une confusion
imp_implementatationwithblock (bloc: anyobject!) Ne prend qu'un paramètre AnyObject en tant que paramètre et retourne un IMP
Son trouvé dans les références d'exécution de l'objectif-c
Comment puis-je lancer
() -> () code> dans
anyObject code>? p>
AVERTISSEMENT FORT>: Cette réponse comprend une fonctionnalité non documentée et dangereuse à Swift. Je doute que cela passe la revue d'AppStore. P> let f: ()->() = { println("test") } let imp = imp_implementationWithBlock( unsafeBitCast( f as @objc_block ()->(), AnyObject.self ) )
Qu'est-ce que 'F'? Est-ce la fermeture?
Alors pourquoi APPLE A FUNC IMP_IMPLEVEMENTATIONWIBLOCK (_ Block: anyObject!) -> IMP CODE> dans la référence LIB Si vous avez besoin de ce code que vous avez posté? Bogue?
Le code Obj-C peut passer des blocs à Swift AnyObject code> Type Paramètre.
Si vous souhaitez ajouter ceci comme une extension, vous êtes libre de l'utiliser: Extension UIBARBUTTONITEM {COMPIENCE INIT (Titre: String?, Style: UibarbuttonItemStyle, Hangler: () -> () -> ()) {Imple Imp = Imp_ImplementaationwithBlock (Infarebitcast (Handler comme @OBJC_Block () -> (), anyobject.elf)) Class_addmethod (Uibarbuttonitem.elf, "Handler", Imp, "V @:") Self.Init (Titre: Titre, Style: Style, Target: Nil , action: "gestionnaire") self.target = auto}} code>
Je ne suis pas sûr que cette extension fonctionne comme prévu. Pour autant que je sache, la méthode est une propriété de classe, pas une instance locale. Donc, je pense que ces résultats chaque instance partage le même gestionnaire, non?
HMM peut-être que la méthode sera créée pour chaque sauf que celles que j'ajoute le gestionnaire pour essayer de l'appeler. Mais je vais le tester plus loin.
Devrait utiliser @convention code> au lieu de
@OBJC_block code>
Cela a fonctionné pour moi:
let myBlock: @objc_block () -> Void = { } var mf : AnyObject = unsafeBitCast(myBlock, AnyObject.self)
Vous pouvez écrire une enveloppe, puis transmettez-la à la fonction
class ObjectWrapper<T> { let value :T init(value:T) { self.value = value } } let action = ObjectWarpper(value: {()->() in // something })
Dans Swift 2, vous devez utiliser @convention code> au lieu de
@OBJC_block code>. Voir Attribut de type
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
}
Utiliser tout objet code> (le protocole sur lequel tous les types sont conformes implicitement) em>
Dans Swift 4.x (je pense que fonctionne aussi dans 3.x), déclarant simplement la fermeture comme @convention (bloc) code> devrait suffire à lutter contre la compatibilité:
// define the new implementation
let handler: @convention(block) (UIBarButtonItem) -> Void = { _ in }
// inject it into the class
class_addMethod(NSClassFromString("UIBarButtonItem"), sel_registerName("handler"), imp_implementationWithBlock(handler), "v@:")
Avez-vous essayé d'utiliser
réinterpretcast () code>?