2017-06-20 84 views
6

我有我在Xcode 8.3.3(雨燕3.1)項目下面的代碼:斯威夫特4向後兼容性

let font = CGFont(provider!) 
CTFontManagerRegisterGraphicsFont(font, &error) 

但在Xcode 9 Beta版(斯威夫特4),我收到以下錯誤:

Value of optional type 'CGFont?' not unwrapped; did you mean to use '!' or '?'?

錯誤是因爲現在需要CGDataProviderinitializer for CGFont返回一個可選項。

但是當我申請的修復:

let font = CGFont(provider) 
CTFontManagerRegisterGraphicsFont(font!, &error) 

的代碼在Xcode 8.3.3不再編譯與雨燕3.1,因爲字體是不可選的,因此不與!發揮很好。

有沒有辦法讓這兩個版本的Xcode工作? Swift 4是否應該向後兼容(使用Swift 3編譯器編譯)?

+0

我想說這是Core Graphics中的一個突破性的變化(初始化器已經成爲failable),所以它與Swift 4無關。但我認爲你可以使用條件編譯來解決這個問題。 –

回答

4

最後我用它允許向後兼容性沒有條件編譯(想法來自this blog post採取)以下方法:

func optionalize<T>(_ x: T?) -> T? { 
    return x 
} 

這樣在Xcode 8和9的Xcode我都可以使用:

guard let font = optionalize(CGFont(provider)) else { 
    return 
} 
CTFontManagerRegisterGraphicsFont(font, &error) 
+1

傷害了這個,但我贊成這個。 –

7

這是Core Graphics中非Swift本身的突破性變化。 API已經改變,初始化程序現在已經失效。

使用conditional compilation,使你的代碼編譯兩個3.1和4.0編譯器:

#if swift(>=4.0) 
let font = CGFont(provider!) 
#else 
let font = CGFont(provider)! 
#endif 

CTFontManagerRegisterGraphicsFont(font, &error) 
+0

如果我使用這個,那麼即使在Xcode 9中我也注意到了我正在打'else'的情況。所以我去了我的項目設置,並將Swift語言版本更改爲Swift 4.0。但現在如果我打開Xcode 8然後它抱怨一個不支持的迅速版本 –

+0

@AdamJohns也許問題是,新的編譯器仍處於測試階段,所以它可能有一個像4.0.beta版本...嘗試將條件編譯語句中的版本更改爲3.3(或其他不存在的3.x版本)。 或者,爲避免猜測,運行'swiftc --version'作爲構建階段腳本之一,以查看Xcode 9和8.3中Swift編譯器的確切版本。 也許Xcode 9使用舊版本的命令行工具(檢查Xcode設置中的位置選項卡)。 –