自动发布不安全的可变指针<字符串?>崩溃 - 编译器中的错误?



我正在慢慢地将我的代码库迁移到Swift,并遇到了一个奇怪的崩溃,我正在用非nil字符串填充AutoreleasingUnsafeMutablePointer<String?>。下面是一些按比例缩小的代码:

extension String {
    func getRegexVariableNamed(name: String, forRegexString regexString: String) -> String? {
        /** ... **/
        return "TO BE IMPLEMENTED".lowercaseString // Using lowercase to prevent the compiler from inlining
    }
}
class XYZ {
    func extractInformation(info1: AutoreleasingUnsafeMutablePointer<String?>, info2: AutoreleasingUnsafeMutablePointer<String?>, info3: AutoreleasingUnsafeMutablePointer<String?>, info4: AutoreleasingUnsafeMutablePointer<String?>, fromSource source: String) -> Bool {
        guard let vp = source.getRegexVariableNamed("ID", forRegexString: "vp=(?P<ID>\d+)") else {
            return false
        }
        info4.memory = vp
        info1.memory = "ABC"
        info2.memory = "DEF"
        info3.memory = "GHI" + vp
        return true
    }
}
// Code in playground
let obj = XYZ()
let info1 = AutoreleasingUnsafeMutablePointer<String?>()
let info2 = AutoreleasingUnsafeMutablePointer<String?>()
let info3 = AutoreleasingUnsafeMutablePointer<String?>()
let info4 = AutoreleasingUnsafeMutablePointer<String?>()
if !obj.extractInformation(info1, info2: info2, info3: info3, info4: info4, fromSource: "") {
    print("NO")
}else{
    print("YES")
}

应用程序(同样适用于操场)崩溃与error: Playground execution aborted: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).

在方法extractInformation(...)中将字符串设置为AutoreleasingUnsafeMutablePointer时发生此异常。

我想检查一下我是否在这里做错了什么,然后再向苹果公司报告这个bug。

顺便说一句,我在OS X 10.10.5上使用最新的Xcode 7 beta(6)。

注::我知道更快速的方法是创建一个返回结构体的方法,而不是使用这些自动释放指针,但如上所述,我正在慢慢地从ObjC移动,所以我需要它(目前)向后兼容。

使用Xcode 7.0.1,我可以使您的代码工作,与一些更改。

首先,在使用Swift with Cocoa和Objective-C (Swift 2)指南("自动释放指针"一章)中,它说一个函数声明为一个AutoreleasingUnsafeMutablePointer<Type>可以接受一个Typeinout表达式。

因此,代码可以修改如下:
let info1: String?
let info2: String?
let info3: String?
let info4: String?
if !obj.extractInformation(&info1, info2: &info2, info3: &info3, info4: &info4, fromSource: "") {
    print("NO")
}else{
    print("YES")
}

但是,它仍然不能工作。

然而,在同一页中,它说AutoreleasingUnsafeMutablePointer<Type>应用于类型映射。我不知道这是否是它不起作用的原因,很难猜测背后发生了什么,但是如果你用NSString替换String,你会得到一个结果。
extension String {
    func getRegexVariableNamed(name: String, forRegexString regexString: String) -> String? {
        /** ... **/
        return "TO BE IMPLEMENTED".lowercaseString // Using lowercase to prevent the compiler from inlining
    }
}
class XYZ {
    func extractInformation(info1: AutoreleasingUnsafeMutablePointer<NSString?>,
                            info2: AutoreleasingUnsafeMutablePointer<NSString?>,
                            info3: AutoreleasingUnsafeMutablePointer<NSString?>,
                            info4: AutoreleasingUnsafeMutablePointer<NSString?>,
                            fromSource source: String) -> Bool {
        guard let vp = source.getRegexVariableNamed("ID", forRegexString: "vp=(?P<ID>\d+)") else {
            return false
        }
        info4.memory = vp
        info1.memory = "ABC"
        info2.memory = "DEF"
        info3.memory = "GHI" + vp
        return true
    }
}
// Code in playground
let obj = XYZ()
var info1: NSString?
var info2: NSString?
var info3: NSString?
var info4: NSString?
if !obj.extractInformation(&info1, info2: &info2, info3: &info3, info4: &info4, fromSource: "") {
    print("NO")
}else{
    print("YES")
    info1                // "ABC"
    info2                // "DEF"
    info3                // "GHIto be implemented"
    info4                // "to be implemented"
}

最新更新