Ios 任意对象的快速闭包
我正在尝试使用这个方法:Ios 任意对象的快速闭包,ios,objective-c,swift,objective-c-runtime,Ios,Objective C,Swift,Objective C Runtime,我正在尝试使用这个方法:class\u addMethod(),在Obj-c中,它是这样使用的: class_addMethod([self class], @selector(eventHandler), imp_implementationWithBlock(handler), "v@:"); 我在Swift中这样使用它: class_addMethod(NSClassFromString("UIBarButtonItem"), "handler", imp_implementationW
class\u addMethod()
,在Obj-c中,它是这样使用的:
class_addMethod([self class], @selector(eventHandler), imp_implementationWithBlock(handler), "v@:");
我在Swift中这样使用它:
class_addMethod(NSClassFromString("UIBarButtonItem"), "handler", imp_implementationWithBlock(handler), "v@:")
它是uibarbuttoneim
的扩展,您可能已经了解到了这一点
imp_implementationWithBlock
接受类型为AnyObject的参数代码>
如何将()->()
强制转换为任何对象
我曾尝试将其强制转换为:处理程序为AnyObject
,但它给了我一个错误,告诉我:()->()不符合协议“AnyObject”
。您只能将其强制转换为任何
可以表示任何类类型的实例AnyObject
可以表示任何类型的实例,包括函数类型Any
()->()
强制转换为任何对象
警告:此答案包括Swift中未记录和不安全的功能。我怀疑这是否通过AppStore审查
let f: ()->() = {
println("test")
}
let imp = imp_implementationWithBlock(
unsafeBitCast(
f as @objc_block ()->(),
AnyObject.self
)
)
这对我起了作用:
let myBlock: @objc_block () -> Void = {
}
var mf : AnyObject = unsafeBitCast(myBlock, AnyObject.self)
您可以编写一个包装器,然后将其传递给函数
class ObjectWrapper<T> {
let value :T
init(value:T) {
self.value = value
}
}
let action = ObjectWarpper(value: {()->() in
// something
})
类对象包装器{
let值:T
初始值(值:T){
自我价值=价值
}
}
让action=ObjectWarpper(中的值:{()->())
//某物
})
在Swift 2中,您应该使用@convention
而不是@objc_block
。请参阅
使用
任何
对象(所有类型隐式符合的协议)
在Swift 4.x中(我认为在3.x中也适用),仅将闭包声明为@convention(block)
就足以解决兼容性问题:
// 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@:")
但是,从Swift 3开始,如果引用来自Objective-C,则将
AnyObject
转换为Any
,因此即使没有@约定(块),代码也会编译
part,但是它会在运行时崩溃,因为编译器不会将Swift闭包转换为Objective-C块。您是否尝试过使用reinterpretCast()
?但是是否有其他方法可以这样做?您是否尝试过传递选择器(“处理程序”)
?能否显示imp\u implementationWithBlock
的签名?错误不是选择器部分,而是导致混淆的imp\u implementationWithBlock()imp\u implementationWithBlock(block:AnyObject!)仅将AnyObject作为参数并返回在Objective-C运行时引用中找到的IMPIts什么是“f”?它是闭包吗?那么为什么Apple afunc imp_implementationWithBlock(block:AnyObject!)->IMP
在lib参考中,如果您需要发布的代码?Bug?Obj-C代码可以将块传递给SwiftAnyObject
类型参数。如果您想将其添加为扩展,您可以自由使用它:扩展UIBarButtonim{便利init(标题:String?,样式:UIBarButtonimStyle,处理程序:()->()){let imp=imp_implementationWithBlock(unsafeBitCast(handler as@objc_block()->(),AnyObject.self))class_addMethod(uibarbuttoneim.self,“handler”,imp,“v@:”)self.init(title:title,style:style,target:nil,action:“handler”)self.target=self}}
应使用@约定
而不是@objc_块
let aBlock: (view: View) -> Void = { view in /**/ }
let block:Any? = aBlock
// 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@:")