從OC到swift的一些總結

最近工作不是很忙,我花了兩個星期的時間學習了一些swift。雖然swift出來快兩年了,但是我一直沒有去學習。近來聽好多朋友說,他們已經開始用swift開發了,我決定學習一下swift基礎的東西,在這裏列出我一些學習總結。我不善於寫文章,我就大片的粘上代碼好了,有OC基礎的人,基本上一看就懂了。

swift幾個詭異符號的意義

蘋果總是能弄出一些與衆不同的代碼書寫方式,比如oc中的字符串寫法。果然swift也一樣,我在寫一些代碼的時候總是彈出警告,點擊修復,系統會幫我加上一個問好(?)或者歎號(!),我但是就有點蒙了,這是什麼意思呢?我沒有系統看過swift的東西,直接按照oc的基礎自己琢磨着寫,導致好多的坑。那麼這兩個符號到底什麼意思呢?我開始在找資料,原來這裏有大學問啊!我先告訴說答案吧,問號(?)表示可選值或顯示拆包,歎號(!)表示隱式拆包。
一切的原因在於一個swift的一個新的類型:optional類型(可選值,可以有值,也可以沒有值),這是oc沒有的類型。在oc中聲明一個變量,可以不用賦初始值,因爲系統會給變量初值。在swift中,變量是沒有默認值的,所以使用變量之前必須賦初始值。當在聲明一個變量不想給初始值的時候,就可以聲明一個optional類型,例如:

var delegate : XXXDelegate?

在調用這個變量的時候,在後面也要加上“?”,如

self.delegate?.btnsAction(btn)

這樣的實質就是:當Optional沒有值時,返回的nil其實就是Optional.None,即沒有值。除了None以外,還有一個Some,當有值時就是被Some包裝的真正的值,所以我們拆包的動作其實就是將Some裏面的值取出來。當變量不可能爲空的時候,就可以用隱式拆包,就是在變量後面跟”!“。比如聲明的時候:

var delegate : XXXDelegate! 

這樣在調用的時候變量後面就什麼都不用加了。聲明的顯示可選值,也可以用!的方式調用。補充一點,在oc中,nill表示的是指針,只有對象纔可以用nill,而在swift中,nill表示沒有值,Int,Bool等在沒有值得時候也是nill。
相關鏈接:
http://blog.csdn.net/woaifen3344/article/details/30244201/
http://blog.csdn.net/zhangao0086/article/details/38640209

懶加載的寫法

在oc中可以,可以重寫get方法來實現懶加載。在swift中用關鍵字layz來實現懶加載。示例代碼:

// 懶加載
       lazy var myTableView : UITableView = {

        var myTableView = UITableView.init(frame:CGRectMake(0, 64, self.view.bounds.width, self.view.bounds.height - 64 - 49), style: UITableViewStyle.Plain)
        myTableView.backgroundColor = kBorderLineColor();
        myTableView.tableFooterView = UIView.init()
        myTableView.delegate = self
        myTableView.dataSource = self

        //2.註冊Cell
        myTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: ID)

        return myTableView

    }()//使用一個閉包來實例化該屬性

屬性的觀察者(willSet/didSet)

willSet在新的值被設置之前調用
willSet觀察器會將新的屬性值作爲常量參數傳入,在willSet的實現代碼中可以爲這個參數指定一個名稱,如果不指定則參數仍然可用,這時使用默認名稱newValue表示。
didSet在新的值被設置之後立即調用
didSet觀察器會將舊的屬性值作爲參數傳入,可以爲該參數命名或者使用默認參數名oldValue。
我們可以didSet方法裏進行一些賦值後的操作,相當於oc中的重寫set方法

var model : UserProfile = UserProfile(){
        didSet{
        nameL.text = model.name
            headerImageV.sd_setImageWithURL(NSURL.init(string: model.avatar_hd), placeholderImage: UIImage.init(named: "timeline_image_placeholder"))
        subL.text = model.userDescription
        }
    }

單例的寫法

網上的swift單例有很多種寫法,我還是在套用oc中的寫法,換湯不換藥

//單例
    class var sharedInstance: LCInterfaceManager {
        struct Static {
            static var onceToken: dispatch_once_t = 0
            static var instance: LCInterfaceManager? = nil
        }
        dispatch_once(&Static.onceToken) {
            Static.instance = LCInterfaceManager()
        }    
        return Static.instance!   
    }

相關鏈接:
http://www.cocoachina.com/swift/20151207/14584.html

協議的寫法

這部分直接上代碼了

//協議代理
protocol xxxViewDelegate{
    func btnsAction(btn:UIButton) -> Void
}
//聲明代理
var delegate : LCProfileHeaderViewDelegate?
//調用
@objc private  func buttonAction(btn:UIButton) -> Void {
        self.delegate?.btnsAction(btn)
    }
//遵守協議,實現代理方法
// MARK: - xxxViewDelegate
extension xxxViewController:xxxDelegate{
    func btnsAction(btn: UIButton) {
        if btn.tag == 101 {
            let VC = LCFridensListVC.init()
            self.navigationController!.pushViewController(VC, animated: true)
        }
    }
}

閉包反向傳值

子這裏我不去講解swift閉包寫法的原理,大家可以去網上學習,教程很多。我要舉一個運用閉包實現方向傳值的例子,相當於oc之中的block用法。
需求:AVc跳轉到BVc中,在BVc中設置AVc的背景色爲隨機色。
AVc中的代碼

import UIKit

let ID = "Cell"
class  ViewController: UIViewController{

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(true)

    }
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
         weak var weakSelf = self
        let VC = LCSTestVC.init()
        VC.initBack { (changeToColor) in
            weakSelf?.view.backgroundColor = changeToColor
        }
      self.presentViewController(VC, animated: true) {}

    }
    override func viewDidLoad(){
        super.viewDidLoad()

}
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

BBC中的代碼

import UIKit

class LCSTestVC: UIViewController {
    typealias changeLastVcBacgroundColor = (color:UIColor)->()
    var myFunc = changeLastVcBacgroundColor?()
    func initBack( mathFunction:(changeToColor:UIColor)->() ){
        myFunc = mathFunction
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.blueColor()
    }
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let r:CGFloat = CGFloat(CGFloat(random())/CGFloat(RAND_MAX))
        let g:CGFloat = CGFloat(CGFloat(random())/CGFloat(RAND_MAX))
        let b:CGFloat = CGFloat(CGFloat(random())/CGFloat(RAND_MAX))
        myFunc!(color: UIColor.init(red: r , green: g, blue: b, alpha: 1.0))
        self.dismissViewControllerAnimated(true) {
        }
    }
}

枚舉的寫法

enum buttonType : Int{
        case back = 1
        case search = 2
        case more = 3 
    }

選擇多個可選值的寫法

let calendarUnit : NSCalendarUnit = [.Year , .Month , .Day ,.Hour, .Minute , .Second]

swift工具類的寫法

swift中沒有宏的概念,那麼怎麼實現類似於oc中pch文件中的定義全局宏的方法呢?答案是可以利用全局函數。

import Foundation
import UIKit
let kScreenWidth = UIScreen.mainScreen().bounds.size.width
let kScreenHeight = UIScreen.mainScreen().bounds.size.height

func DLog(input:AnyObject, function:String = #function, line:Int = #line){
    #if DEBUG
        print("- <func: \(function)> <line: \(line)>: \(input)")
    #else
    #endif
}
//大字
let kBigTextFont = UIFont.systemFontOfSize(16)
//常規
let kMidTextFont = UIFont.systemFontOfSize(14)
//小字
let kSmallTextFont = UIFont.systemFontOfSize(12)
//邊框粗細
let kBorderLineThickness : CGFloat = 0.8
//cell邊線粗細
let kBorderCellLineThickness : CGFloat = 8
//RGB
func RGBA (r:CGFloat, g:CGFloat, b:CGFloat, a:CGFloat) -> UIColor {
    return UIColor (red: r/255.0, green: g/255.0, blue: b/255.0, alpha: a)
}

重寫系統答應print的內容

class AAA: NSObject {
    override var description: String{
        return "12345"
    }
}

swift與OC混編的總結

現在的swift開發多數會用到混編。swift和oc是通過橋接文件來實現的。無論是在oc創建的項目中還中創建swift文件,還是在swift文件中創建oc文件,第一次都會自動提示建立橋接文件。名字爲:xxx-Bridging-Header.h,並且自動添加文件路徑。如果是導入另一隻中語言的第三方庫,就不會自動生成橋接文件,這時候就需要自己建立一個橋接文件。第一步:新建一個”.h”文件,也就是新建中的”Header.h“文件,名字可以模仿系統的寫法”xxx(demo名字)-Bridging-Header.h“;第二步,橋接文件路徑,在設置Build Settings 中搜索Bridging,結果中Objective-C Brindging Header 中拖入文件路徑(前面的可以寫成$(SRCROOT)/,這樣就會自動生成項目文件路徑,不會因爲換了電腦就找不到文件路徑),編譯一下,就可以了。

在oc項目中引用swift文件,只需導入頭文件

#import "項目名字-Swift.h"

這個文件是隱藏的,在工程中看不見。導入這個文件後就可以在oc使用swift寫的類了。

在swift文件中引用oc的類,在橋接文件中引入需要引用oc的類的頭文件,編譯一下,就可以使用oc的類了。

多返回值函數的運用

swift的中的函數可以有多個返回值,具體的運用還沒有比較好的列子。這裏只是據下一多返回值函數的寫法:
“`
private func createItem(frame:CGRect , topText:String , bottomText:String) ->(button:UIButton ,topLabel: UILabel , bottomLabel:UILabel){
let btn = UIButton.init(frame: frame)
let topL = UILabel.init()
topL.font = UIFont.boldSystemFontOfSize(16)
let bottomL = UILabel.init()
bottomL.font = kMidTextFont
bottomL.textColor = kMinBlackColor()

    topL.text = topText
    topL.sizeToFit()
    topL.frame.size.width = frame.size.width
    topL.textAlignment = NSTextAlignment.Center
    bottomL.text = bottomText
    bottomL.sizeToFit()

    topL.frame.origin.x = btn.frame.size.width/2 - topL.frame.size.width/2
    bottomL.frame.origin.x = btn.frame.size.width/2 - bottomL.frame.size.width/2

    topL.frame.origin.y = btn.frame.size.height/2 - topL.frame.size.height/2 - 4
    bottomL.frame.origin.y = btn.frame.size.height/2 + 4

    btn.addSubview(topL)
    btn.addSubview(bottomL)
    return (btn , topL , bottomL)
}

//調用
let itemsLeft = self.createItem(CGRectMake(0, 0,frame.size.width/3, frame.size.height), topText: “0”, bottomText: “微博”)
itemsLeft.button.tag = 100
itemsLeft.button.addTarget(self, action: #selector(LCProfileHeaderView.buttonAction(_:)), forControlEvents: UIControlEvents.TouchUpInside)
self.statusCountLabel = itemsLeft.topLabel
self.addSubview(itemsLeft.button)

“`

關於xib中自適應的總結

這部分跟swift沒有什麼關係,只是我以前一直在用代碼的方式實現比如lable的大小的自適應。最近發現,其實xib中也可以做這些的。
需求:比如一個label後面跟着一個UIView,label的寬度隨着字數的大小變換,這個功能是可以用xib實現的。
第一步,拖入控件,利用xib來控制好約束,這部分和平常xib的使用沒有區別,不在講述。
這裏寫圖片描述
第二步,選中圖中的label,操作如圖:

這裏寫圖片描述
第三步,保持選中label,操作
這裏寫圖片描述
做完這些操作後,label的橫向約束會變成虛線,大功告成。如果你的功能裏有對最大寬度的控制,可以在layoutSubviews這個方法裏用代碼來控制。
目前我學習到的只有這些,以後有什麼爬出的坑,再跟大家來分享吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章