北京時間2月10日,蘋果在面向開發(fā)者推送iOS 8.3 Beta的同時,還發(fā)布了版本號為6D520o的Xcode 6.3 Beta,其中便包含了iOS 8.3 Beta和OS X v10.10 SDK,并進一步提升了Swift與Objective-C代碼的交互性,而Swift業(yè)已更新至1.2版本。
從Xcode 6.3 Beta Release Notes看出,Xcode 6.3 Beta包含了很多頗為值得開發(fā)者期待的改變,共計50多處改動,同時修改了Objective-C的語法,足見蘋果對Swift語言的重視。而其代碼遷移工具可以幫助開發(fā)者將其代碼從Swift 1.1(Xcode 6.1)升級至Swift 1.2(Xcode 6.3),具體執(zhí)行編輯菜單(Edit)->轉(zhuǎn)換(Convert)-至(To)Swift1.2即可。 具體更新如下:
if let a = foo(), b = bar() where a < b, let c = baz() { }
它允許你測試多種選擇,并且包含一個bool判斷。當然這種情況不包含嵌套判斷。
let x: SomeThing if condition { x = foo() } else { x = bar() } use(x)
這個正常的來說需要var變量用法,盡管這里沒有任何修改的操作。
@objc enum Bear: Int { case Black, Grizzly, Polar }導出到Objective-C:
typedef NS_ENUM(NSInteger, Bear) { BearBlack, BearGrizzly, BearPolar };
import Darwin var devNullStat = stat() stat("/dev/null", &devNullStat)
如果一個結(jié)構(gòu)體的元素不能被正確的初始化為0(比如被標記為新的_nonnull標示符時),這個默認的構(gòu)造器將會終止。
toString(Int.self) // 打印 “Swift.Int" println([Float].self) // 打印 "Swift.Array<Swift.Float>” println((Int, String).self) // 打印 "(Swift.Int, Swift.String)"
func autoreleasepool(@noescape code: () -> ()) { pushAutoreleasePool() code() popAutoreleasePool() }
import Foundation func log(s: String) { println(x) } let ns: NSString = "some NSString" // Okay log(ns) // 錯誤 // "'NSString' 不能轉(zhuǎn)換為 'String'"為了完成橋接轉(zhuǎn)換,需要用顯式轉(zhuǎn)化符標注:
log(ns as String) // succeeds從Swift類型到Objective-C類型的橋接隱式轉(zhuǎn)換依然被允許,比如:
func nsLog(ns: NSString) { println(ns) } let s: String = “some String” nsLog(s) // okay: implicit conversion from String to NSString is still permitted
//以前我們這樣寫: func assert(predicate : @autoclosure () -> Bool) {… } //現(xiàn)在需要這樣寫: func assert(@autoclosure predicate : () -> Bool) {… }
func curryUnnamed(a: Int)(_ b: Int) { return a + b } curryUnnamed(1)(2) func curryNamed(first a: Int)(second b: Int) -> Int { return a + b } curryNamed(first: 1)(second: 2)
class A : NSObject { var property: String = "Hello" // 注意: Objective-C 方法 'setProperty:’ // 以前這里“屬性”這里是通過setter聲明 } extension A { func setProperty(str: String) { } // 錯誤:方法"setProperty" // 重復聲明了Objective-C方法 //'setProperty:' }同樣地檢查在Objective-C中重寫:
class B : NSObject { func method(arg: String) { } // 注意:重寫操作 // 這里含有類型:'(String) -> ()' } class C : B { func method(arg: [String]) { } // 錯誤: 重寫的選擇器方法含有不匹配的類型'([String]) -> ()' }和協(xié)議的適配性一樣:
class MyDelegate : NSObject, NSURLSessionDelegate { func URLSession(session: NSURLSession, didBecomeInvalidWithError: Bool){ } // 錯誤:Objective-C 方法 'URLSession:didBecomeInvalidWithError:' //由方法提供: 'URLSession(_:didBecomeInvalidWithError:)' // 和可選類型的需求方法相沖突: // 'URLSession(_:didBecomeInvalidWithError:)' 在協(xié)議 // 'NSURLSessionDelegate' }
struct Point { var x, y: Double } extension Point : Printable { var description: String { return "(\(x), \(y))" } } var p1 = Point(x: 1.5, y: 2.5) println(p1) // prints "(1.5, 2.5)”
let animationCurve = nsafeBitCast(userInfo[UIKeyboardAnimationCurveUserInfoKey].integerValue, UIViewAnimationCurve.self)現(xiàn)在可以寫為:
let animationCurve = UIViewAnimationCurve(rawValue: userInfo[UIKeyboardAnimationCurveUserInfoKey].integerValue)!
class Base { func foo(x: String) -> String? { return x } } class Derived: Base { override func foo(x: String?) -> String { return x! } }
-(void)registerNib:(nonnull UINib *)nib forCellReuseIdentifier:(nonnull SString *)identifier; -(nullable UITableViewCell *)cellForRowAtIndexPath:(nonnull SIndexPath)indexPath; @property (nonatomic, readwrite, retain, nullable) UIView *backgroundView;這個nullability標示符影響了Objective-C API在Swift的可選類型值,nonnull標示符標示的類型將會以非可選的類型的導入,這個用來替代隱式解封可選類型如(e.g., UINib!)。而nullable標示符標示的類型則會以可選類型導入(如UITableViewCell?),所以下面的API在Swift中表現(xiàn)如下:
func registerNib(nib: UINib, forCellReuseIdentifier identifier: String) func cellForRowAtIndexPath(indexPath: NSIndexPath) -> UITableViewCell? var backgroundView: UIView?
void enumerateStrings(__nonnull CFStringRef (^ __nullable callback)(void));這里,它自身的回調(diào)函數(shù)是nullable的,但是它的回調(diào)函數(shù)的返回類型為nonnull,所以這個API在Swift以如下方式使用:
func enumerateStrings(callback: (() -> CFString)?)總的來說,可空特性標示符有三種,可以用雙下劃線(用在任何指針類型),或者沒有下劃線的(用在Objective-C屬性,方法結(jié)果類型或者方法參數(shù)類型)。
Type qualifier spelling |
Objective-C property/method spelling |
Swift view |
Meaning |
__nonnull |
nonnull |
Non-optional, 如: UINib |
該值永遠不會為nil(有一種例外是可能參數(shù)傳遞時傳入的消息為空) |
__nullable |
nullable |
Optional, 如:UITableViewCell? |
該值可能為nil |
__null_unspecified |
null_unspecified |
隱式解封可選類型如, NSDate! |
不確定該值是否為空(很少見) |
#pragma clang assume_nonnull begin // … -(void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier; -(nullable UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath)indexPath; @property (nonatomic, readwrite, retain, nullable) UIView *backgroundView; // … #pragma clang assume_nonnull end
@property (nonatomic, retain, null_resettable) UIColor *tintColor;這樣的API在Swift使用隱式強制解封的方法使用:
var tintColor: UIColor!
void executeImmediately(__attribute__((noescape)) void (^callback)(void);將被影射到Swift為:
func executeImmediately(@noescape callback: () -> Void)
作者簡介:
王芳杰 目前就職于疊拓信息技術(shù)有限公司,擔任疊拓NGN中國人力資源培養(yǎng)經(jīng)理、疊拓NGN中國售前經(jīng)理,《老碼說編程之玩轉(zhuǎn)Swift江湖》一書作者。