Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 任意对象的快速闭包_Ios_Objective C_Swift_Objective C Runtime - Fatal编程技术网

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
    可以表示任何类型的实例,包括函数类型
苹果公司,“快速编程语言”,iBooks

如何将
()->()
强制转换为
任何对象

警告:此答案包括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 a
func imp_implementationWithBlock(block:AnyObject!)->IMP
在lib参考中,如果您需要发布的代码?Bug?Obj-C代码可以将块传递给Swift
AnyObject
类型参数。如果您想将其添加为扩展,您可以自由使用它:
扩展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@:")