Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.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 转换非托管<;AnyObject>;!斯威夫特_Ios_Swift - Fatal编程技术网

Ios 转换非托管<;AnyObject>;!斯威夫特

Ios 转换非托管<;AnyObject>;!斯威夫特,ios,swift,Ios,Swift,我试图获得现有目标C类的一个方法的结果,称为usingperformSelector let result = controlDelegate.performSelector("methodThatReturnsBOOL") as? Bool 我需要将这个结果转换成Bool类型的Swift 上面提到的代码给出了一个警告 “从'Unmanaged!'转换为不相关的类型'Bool'总是失败” 结果总是“false”,即使方法返回YES也是如此 对于将结果转换为Bool有什么建议吗 返回工具的方法的

我试图获得现有目标C类的一个方法的结果,称为usingperformSelector

let result = controlDelegate.performSelector("methodThatReturnsBOOL") as? Bool
我需要将这个结果转换成Bool类型的Swift

上面提到的代码给出了一个警告

“从'Unmanaged!'转换为不相关的类型'Bool'总是失败”

结果总是“false”,即使方法返回YES也是如此

对于将结果转换为Bool有什么建议吗

返回工具的方法的签名

- (BOOL)methodThatReturnsBOOL
{
    return YES;
}

这已经有很长一段时间没有答案了,所以我补充了我在这一过程中学到的东西

要转换Objective C方法返回的
BOOL
值,只需使用

if let result = controlDelegate.performSelector("methodThatReturnsBOOL") {
    print("true")
} else {
    print("false")
}
如果需要,您还可以在此处为Swift
Bool
指定真/假值


注意:正如许多答案所建议的那样,我尝试使用
takeRetainedValue()
Unmanaged
直接转换到
Bool
,但在这种情况下似乎不起作用。

这是Swift 3中的解决方案,因为方法有点不同。此方法还检查Objective-C对象是否响应选择器,以避免崩溃

import ObjectiveC

let selector = NSSelectorFromString("methodThatReturnsBOOL")

guard controlDelegate.responds(to: selector) else {
    return
}

if let result = controlDelegate.perform(selector) {
    print("true")
}
else {
    print("false")
}

在斯威夫特,你不能很好地做你想做的事。我接受的解决方案的问题是,它利用了0x0恰好是
nil
的思想。事实上,Swift和Objective-C规范并不能保证这一点。这同样适用于布尔值,因为0x0为false,0x1为true只是一个任意的实现决策。除了在技术上不正确外,这也是一个很难理解的代码。如果不考虑大多数平台上的nil指针是什么(32/64位的零),那么所建议的是零意义的

在与WWDC'19的一位工程师交谈了一段时间后,他建议您实际上可以使用
valueFor(forKey:)
,键是函数名/选择器描述。这是因为Obj-C运行时将实际执行具有给定名称/键的任何函数以计算表达式。这仍然有点不成熟,因为它需要了解Objective-C运行时,但是它保证独立于平台和实现,因为
valueFor(forKey:)
返回一个
Any?
,可以将其转换为
Int
Bool
,而没有任何问题。通过使用内置类型转换而不是推测0x0或0x1的含义,我们避免了解释nil指针的整个问题

例如:

@objc func doThing() -> Bool{
    return true
}

let target=someObjectWithDoThing
让selectorCallResult=target.value(forKey:“doThing”)
让intResult=选择或调用结果为?Int//可选
让boolResult=选择或调用结果为?Bool//可选
与我的回答类似,这可以通过
@convention(c)
来实现:

let selector: Selector = NSSelectorFromString("methodThatReturnsBOOL")
let methodIMP: IMP! = controlDelegate.method(for: selector)
let boolResult: Bool = unsafeBitCast(methodIMP,to:(@convention(c)(Any?,Selector)->Bool).self)(controlDelegate,selector)

此特定语法自Swift 3.1起可用,也可以在Swift 3中使用一个额外变量。

是否可以发布返回布尔的
方法的签名?
?不能将PerformSelect()与返回布尔的方法一起使用。从文档中可以看到:“对于返回对象以外的任何方法,请使用NSInvocation。”然而,NSInvocation在Swift中不可用(据我所知)。@Alladinian:Question updated(这只是一个返回YES/NO的简单的Objective C方法)@MartinR:是的,我研究了NSInvocation,但它在Swift中不可用(目前)。虽然performSelector()工作正常,但问题只是如何捕获返回的BOOL值。关于如何实现这一点,还有其他建议吗?我们在现有的Objective C类中有一个id类型的委托。我们需要通过Swift类对该委托执行选择器,Swift类又是现有目标C类的子类。调用中缺少参数“withObject”、“afterDelay”的参数
let selector: Selector = NSSelectorFromString("methodThatReturnsBOOL")
let methodIMP: IMP! = controlDelegate.method(for: selector)
let boolResult: Bool = unsafeBitCast(methodIMP,to:(@convention(c)(Any?,Selector)->Bool).self)(controlDelegate,selector)