AutoreleasingUnsafeMutablePointer<String?> Сбой - ошибка в компиляторе?

Я медленно перемещаю свою кодовую базу в Swift и столкнулся со странным сбоем, где я заполняю 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).

Это исключение происходит при установке строки в AutoreleasingUnsafeMutablePointer в методе extractInformation(...),

Я хотел проверить, не делаю ли я здесь что-то не так, прежде чем сообщить об этом как об ошибке в Apple.

Кстати, я использую последнюю бета-версию Xcode 7 (6) на OS X 10.10.5.

PS: я знаю, что более быстрый подход заключался бы в создании метода, который возвращает структуру вместо использования этих автоматически высвобождающих указателей, но, как уже упоминалось, я медленно ухожу от ObjC, поэтому мне нужно (пока) чтобы быть в обратном направлении. совместимы.

1 ответ

С Xcode 7.0.1 я могу заставить ваш код работать, с некоторыми изменениями.

Прежде всего, в руководстве " Использование Swift с какао и Objective-C (Swift 2)" (глава "Авторелизирование указателей") говорится, что функция, объявленная как AutoreleasingUnsafeMutablePointer<Type> может принять inout выражение того же Type,

Таким образом, код можно изменить следующим образом:

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> применяется для отображения типов классов. Я не знаю, является ли это причиной того, что это не работает, трудно угадать, что происходит позади, но если вы замените String с NSString, вы получите результат.

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"
}
Другие вопросы по тегам