2015-08-31 34 views
2

我正在慢慢將我的代碼庫遷移到Swift,並遇到了一個奇怪的崩潰,我用非零字符串填充了AutoreleasingUnsafeMutablePointer<String?>。下面是一些按比例縮小代碼: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崩潰。

我想檢查一下,如果我在這裏沒有做錯什麼,那麼我會將此報告爲Apple的一個錯誤。

順便說一句我在OS X 10.10.5上使用最新的Xcode 7 beta(6)。 PS:我知道更多的Swift-ly方法是使一個方法返回一個結構,而不是使用這些自動釋放指針,但如前所述,我正在從ObjC緩慢移動,所以我需要它(現在)向後兼容。

+0

因爲似乎沒有人能夠指出問題的代碼,而不是編譯器,我已經提交了這個錯誤給蘋果公司。 –

回答

1

使用Xcode 7.0.1,我可以讓你的代碼工作,但有一些變化。

首先,在Using Swift with Cocoa and 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" 
} 
+0

有趣的是,它與NSString一起工作 - 因爲即使是帶有String的純Swift代碼也不起作用。我最終將所有使用這種類型的類重寫到了Swift中,並將所有變量嵌入到了一個結構體中,所以這不再是一個問題。但這絕對是使我認爲Swift根本不是生產就緒的問題之一 - 就像大多數Apple技術一樣,它們在推出兩年後開始使用。 –