2014年6月20日

Swift class 與Objective-C 特性

從Obj-C繼承的Class

Swift可以繼承Obj-C的class
範例:

SWIFT
  • import UIKit
  • class MySwiftViewController: UIViewController {
  • // define the class
  • }

Protocols
在Swift我們可以使用原本Obj-C的protocol
例如:

SWIFT
  • class MySwiftViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
  • // define the class
  • }

Outlets and Actions
Swift 中IBAction 和IBOutlet的使用:

SWIFT
  • class MyViewController: UIViewController {
  • @IBOutlet var button: UIButton
  • @IBOutlet var textFields: UITextField[]
  • @IBAction func buttonTapped(AnyObject) {
  • println("button tapped!")
  • }
  • }
參數的屬性

Strong and Weak
Strong是Swift的預設值,weak須另外指定,weak只能被用在optional的型態

Read/ Write and Read-Only
Swift中沒有readwrite和readonly的屬性
使用let,把值宣告成常數,達到read-only的效果
使用var,宣告為變數達到read/ write的效果

Objective-C和Swift的互動

初始化

  • UITableView的例子:

    • Objtive C
    • UITableView *myTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
    • Swift
    • let myTableView: UITableView = UITableView(frame: CGRectZero, style: .Grouped)


在Swift中,我們不需要進行alloc和init,因為Swift已經幫我們自動處理好。

  • UIColor的例子:

    • Objtive C
    • UIColor *color = [UIColor colorWithRed:0.5 green:0.0 blue:0.5 alpha:1.0];
    • Swift
    • let color = UIColor(red: 0.5, green: 0.0, blue: 0.5, alpha: 1.0)











存取屬性

Swift和Obj-C一樣,存取屬性使用點
   SWIFT
  • myTextField.textColor = UIColor.darkGrayColor()
  • myTextField.text = "Hello world"
  • if myTextField.editing {
  • myTextField.editing = false
  • }

方法

從Swift中呼叫Obj-C的方法,使用點符號來呼叫
OBJECTIVE-C
  • [myTableView insertSubview:mySubview atIndex:2];
SWIFT
  • myTableView.insertSubview(mySubview, atIndex: 2)

AnyObject = id

Swift有一種protocol叫做AnyObject來代表所有的object,就如同Obj-C中的id一樣。






SWIFT
  • var myObject: AnyObject = UITableViewCell()
  • myObject = NSDate()


nil

在obj-C中,所有的值都可能為nil,而在Swift中,只有被宣告成optional的值有可能為nil(代表值遺失)。

Extensions

在Swift中,extension可以擴展現有classs(struct、enum)的屬性
例如在CGRect中新增Area屬性




SWIFT
  • extension CGRect {
  • var area: CGFloat {
  • return width * height
  • }
  • }
  • let rect = CGRect(x: 0.0, y: 0.0, width: 10.0, height: 50.0)
  • let area = rect.area
  • // area: CGFloat = 500.0


Closures


OBJECTIVE-C
  • void (^completionBlock)(NSData *, NSError *) = ^(NSData *data, NSError *error) {/* ... */}



SWIFT
  • let completionBlock: (NSData, NSError) -> Void = {data, error in /* ... */}

Obj-C block和Swift的Closure是相容的,所以可以把Swift的closure傳給原本obj-c需要block的部分。

Object的比較
== (2個等號)是比較內容
===(3個等號)是比較物件是不是同一個

Swift Type的相容性
若定義任一Swift class繼承Obj-C class(或是繼承NSObject),這個class會自動相容於obj-C;如果Swift並不是衍生自Obj-C,但是你想在Obj-C中使用,就要加上@obj的描述。
也就是說,@objc可以讓Swift的API在Obj-C中使用,例如
在Swift中的function
fun playSong(name: String )
在Obj-C中會被翻譯成
-(void)playSong:(NSString*)name;

有一個例外情況是初始化的時候,編譯器會自動加上initWith並將字首大寫
比如說Swift中的初始化函數
init(songName:String, artist: String)
會被翻譯成Obj-C中的
initWithSongName:(NSString*)songName artist:(NSString*)artist

因為Swift中可以使用任何unicode的字元當作名稱,所以在Swift中也可以指定轉換成obj-C中的名稱

例如:

SWIFT
  • @objc(Squirrel)
  • class Белка {
  • @objc(initWithName:)
  • init (имя: String) { /*...*/ }
  • @objc(hideNuts:inTree:)
  • func прячьОрехи(Int, вДереве: Дерево) { /*...*/ }
  • }

Objective-C Selectors

在Swift中,原本的selector被selector struct取代,例如
let mySelector: Selector = ""tappedBtn: 就可以轉換成選擇器
而原本Obj-C中的performSelector 並沒有被導入到Swift中,因為他們是不安全的