作为AnyObject的Swift闭包

Arb*_*tur 10 objective-c objective-c-runtime ios swift

我试图使用这种方法:class_addMethod()在Obj-c中使用这样的方法:

class_addMethod([self class], @selector(eventHandler), imp_implementationWithBlock(handler), "v@:");
Run Code Online (Sandbox Code Playgroud)

我在Swift中使用它就像这样:

class_addMethod(NSClassFromString("UIBarButtonItem"), "handler", imp_implementationWithBlock(handler), "v@:")
Run Code Online (Sandbox Code Playgroud)

UIBarButtonItem正如您可能已经想到的那样,它是一个扩展.

imp_implementationWithBlock 采用类型的参数 AnyObject!

我怎么能()->()投入AnyObject

我试图像这样抛出它:handler as AnyObject但是它给了我一个错误说:()->() does not conform to protocol 'AnyObject'

rin*_*aro 9

我怎么能()->()投入AnyObject

警告:此答案包含Swift中未记录和不安全的功能.我怀疑这是通过AppStore审查.

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

let imp = imp_implementationWithBlock(
    unsafeBitCast(
        f as @objc_block ()->(),
        AnyObject.self
    )
)
Run Code Online (Sandbox Code Playgroud)


lea*_*vez 8

您可以编写一个包装器,然后将其传递给该函数

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

let action = ObjectWarpper(value: {()->() in    
    // something
})
Run Code Online (Sandbox Code Playgroud)


onm*_*133 5

在Swift 2中,你应该使用@convention而不是@objc_block.请参见类型属性

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
}
Run Code Online (Sandbox Code Playgroud)