swift 语法备忘

2017-01-21  本文已影响7人  暴风鱼
swift项目中的变量作用域于JavaScript相似。  
    在一个文件的最外层定于的变量为全局变量,这个变量可以在别的文件中直接使用。
    例:
        在 file1 中定义:      var x = 123
        在 file2 中可以直接使用: print(x)
    从这里也可以更容易理解 为什么swift定义类的文件名不要求与类同名。(因为
    一个文件中可以定义多个类和其它全局范围的变量)

Foundation framework 中的类以NS开头,这个NS来自于NeXTSTEP(写Cocoa的公司)

/***********************************************
****************   自动布局   ********************
***********************************************/
Content Hugging Priority // 抗拉能力
Content Compression Resistance Priority // 抗压能力

/***********************************************
*****************   调试器   ********************
***********************************************/
(lldb) po <变量>  //打印变量 Print Object
(lldb) print <变量>  //打印变量 


/***********************************************
*****************    语法   ********************
***********************************************/
    func go(aFunc:(Double,Double)->Double){
        // something...
        aFunc(1,2)
    }

    //通过传递一个匿名函数 调用
    go({(op1:Double, op2:Double) -> Double in
        return op1 + op2
    })

    //由于可以推断出op1 op2的类型 和返回值所以可以省略为
    go({(op1, op2) in return op1 + op2 })

    // 用$0 $0引用传递的参数后可进一步省略为
    go({ $0 + $1 })

    //还可以把这个匿名函数拿外边来
    go(){ $0 + $1 }

    //如果这个匿名函数是这个唯一的参数 ()也可以省略掉
    go{ $0 + $1 }

// switch 语句 注意下面条件的写法
    let a = "abcd"
    switch a{
    case "a":
        print(1)
    case "b","c":
        print(3)
    case let x where x.hasPrefix("abc"):
        print("x:\(x)")
    default:
        print(0)
    }
// if 语句 注意下面条件的写法
    var a:String? = "xa"
    var b:String? = "b"

    // a非nil 且 a以x开头 且 y非nil
    if let x = a where x.hasPrefix("x"),let y = b {
        print("ok|| x->\(x) || y->\(y)")
    }
// 枚举
    // 枚举可以没有类型
    enum e0 {
    case c1
    case c2
    case c3
    }
    // 有类型时会有rawValue
    enum e1:Int {
    case c1
    case c2
    case c3
    }
    print(e1.c1.rawValue)

//!!!只有类的传递是传引用  类只能继承一个父类
// final类 不能被继承
// final方法 不能被override
// static 声明类方法

// Array 数组
    //声明数组 迭代数组
    var a = Array<String>()
    var a2 = [String]()

    let animals = ["Cow","Giraffe","Bird"]
    //animals.append("haha") animals是不可变数组
    let animal = animals[2]

    for animal in animals{
        print("\(animal)")
    }

//Dictionary 字典
    //创建字典
    var d = Dictionary<String,String>()
    var d2 = [String:Int]()

    d2 = ["string1":1,"string2":2]
    let i = d2["string2"]
    let i2 = d2["xx"] //nil
    //迭代字典
    for(key,value) in d2{
        print("\(key) = \(value)")
    }
// Rang 范围
    // Rang的结构类似这样
    struct  Rang<T> {
        var startIndex:T
        var endIndex:T
    }
    //迭代 rang 中的值
    for i in [2...5]{
        print("\(i)")
    }
//func 函数参数
    //函数参数 一个外部名 一个内部名
    func foo(externalName internalName: Int)-> Int{
        let local = internalName
        return local
    }
    let result = foo(externalName: 2) //这样指定参数名 调用


    //函数参数 忽略外部名 一个内部名
    func foo2(internalName: Int)-> Int{
        let local = internalName
        return local
    }
    let result2 = foo2(2) //这样指定参数名 调用



    //函数参数 强制调用时指定参数名
    func foo3(internalName internalName: Int)-> Int{
        let local = internalName
        return local
    }
    let result3 = foo3(internalName: 3) //这样指定参数名 调用

//property observers  属性监视器
    var someProperty: Int = 43{
    willSet{
        print("old is \(someProperty),new is \(newValue)")
    }
    didSet{
        print("now is \(someProperty),old is \(oldValue)")

    }
    }
    someProperty = 33

//Lazy Initialization 惰性初始化
    // 只能用于var 不能用于let 因为let的值在类创建时初始化完毕
    // 当这个变量被用到时,才真正初始化
    lazy var brain = CalculatorBrain()
    //用匿名函数进行初始化
    lazy var someProperty: Type = {
        return <the constructed value>
    }()

// 可失败的初始化 Failable init
    init?(arg1:Type1,...){
        //可以在这里返回 nil 
    }
    // 例如 image 可能为nil
    let image = UIImage(named: "")
    // 可以这样判断
    if let image = UIImage(named: ""){
        print("ok")
    }else{
        print("no..")
    }

// join数组
    ["2","3","4","5"].joinWithSeparator("&")

// casting 强制类型转换
    let x = 1 as Double  //强转成double
    // 如果强转成功   
    if let x = (1.2 as? Int){
        print("ok")
    }else{ //失败
        print("faile")
    }
    // 使用 is
    if 1.2 is Double{
        print("yes")
    }else{
        print("no")
    }
// casting Arrays of AnyObject
    var items:[AnyObject]
    for item in items {
        if let item- = item as? UIBarButtonItem {
            // do something
        }
    }

    for toolbarItem in toolbarItems as [UIBarButtonItem]{
        // do something
    }

    let button:AnyObject
    let title = (button ad UIButton).currentTitle

// 调用字类方法时的判断
    let animal1: Animal = Dog()  //animal 是dog的父类
    // 但是 不能 animal1.jiao() animal1 上没有 jiao(叫)方法
    // 得这样
    if let dog_ = animal1 as? Dog { //尝试将animal1 转成 Dog
        dog_.jiao()
     } 

// functon
    var a = [1,2,3,4]
    a += [2]
    a.first
    a.last
    a.append(22)
    a.insert(55, atIndex: 0)
    a.insertContentsOf([91,92,93], at: 2)
    a.removeAtIndex(1)
    a.removeRange(0...3)
    a.replaceRange(0...1, with: [101,102])
    // map方法
    var sA = a.map{"\($0)"}
    // reduce 方法
    var rA = a.reduce(0) { $0+$1 }

// Type Concersion 类型转换
    var i = Int(36.6)
// Assertions 断言
    assert(validation()!=nil, "the validation funtion returned nil")

// 转成NSString 获取length属性
    let x = "123abc"
    let l = (x as NSString).length
    // 转成NSArray 调用其cjbs 方法
    var a = [1,2,3]
    var x = (a as NSArray).componentsJoinedByString("_")

// NSUserDefaults 用户持久化存储 可以存 “settings”
    let defaults = NSUserDefaults.standardUserDefaults()
    defaults.setObject([1,2,3], forKey: "index1")
    // 同步到硬盘
    defaults.synchronize()

// UIView 只有一个superview  和一个subview数组 subviews
    // 什么button lable 什么的都是UIView的子类
// UIWindow 是UIView的子类 : 处在最顶层
    addSubView(aView:UIView) //添加一个view
    removeFromSuperview()  // 移除view
    contentScaleFactor // 每个点有几个像素

// 在坐标系统中要使用CGFLoat 替代 Double Float...
// CGPoint
    var point = CGPoint(x: 37.0, y: 55.2)
    point.x -= 30
    point.y += 20.0
// CGSize
    var size = CGSize(width: 100.0, height: 50.0)
    size.width += 42.5
    size.height -= 11
// CGRect
    struct  CGRect{
        var origin: CGPoint
        var size: CGSize
    }
    let rect = CGRect(origin: aCGPoint, size: aCGSize)
    // CGRect 的几个属性
    var minX:CGFloat // 左边缘
    var midY:CGFloat //y轴的中点

@IBDesignable  // <- 在storyboard中绘制 这个UIView的子类
class FaceView: UIView {
    @IBInspectable  // <- 在右侧的inspetor中可以设置这些属性
                    // 就像设置button的各个属性
                    // 这里得明确指明变量的类型 才能正常显示
    var color:UIColor = UIColor.blueColor(){ //笑脸线条的颜色
        // 设置新值时请求重绘
        didSet{
            setNeedsDisplay()
        }
    }
}

// Extensions 可以给 类 结构 枚举 增加属性和方法(即使没有源码)
    // 只能增加方法 不能覆盖
    // 不能增加存储属性 即:只能增加计算属性

// Protocols 
    // A way to express an API minimally 
    // 只指定需要的属性和方法

    // 协议也只是一种类型,除了:没有存储 和 实现
    // 协议可以被 class enum struct 实现
    // 协议可以用来作为声明变量时的类型


// from https://github.com/vandadnp/swift-weekly/blob/master/issue11/README.md#inline
    @inline(never) // 声明这个函数never编译成inline的形式
    @inline(__always) // 生命这个函数总是编译成inline的形式
    inline函数可以用 闭包 的形式实现


// 在这里 限定Type1 是user类型 还可以给它添加更多限制
    class User{}
    func testGo<Type1: User> (a1:Type1,a2:Type1)->Int{
        return 0
    }
    var user1 = User()
    var user2 = User()
    var r = testGo(user1, a2: user2)
    print(r)


// inout关键字传引用
    func go(inout a:Int){
        a+=1
    }
    var s = 0
    go(&s)
    //s = 1

// 外部参数名_(可省略) 内部参数名v https://www.natashatherobot.com/swift-init-with-_/
    init(_ v: UInt32)

// 在闭包中 这样声明一个弱指针
    { [unowned self] in
        x = x + 1
        self.show(x)
    }
// 尾随闭包写法
    {(action:UIAlertAction) -> Void in
    
    }
    // 注意这个闭包的写法
    alert.addTextFieldWithConfigurationHandler {
        (textField) in
        textField.placeholder = "导航系统密码!"
    }

b:String?  //这样声明的话
b!.xx   // 这里得unwrap
b!.yy

a:String! //这种类型是Optional 这种类型使用时可以省略unwrap符
a.xx
a.yy  // 可以这样用 省略unwrap


// class var
private extension UIColor {
    // class var 跟 static var相似
    // 用class修饰的可以被子类改变
    class var random:UIColor {
        // ...
    }
}



//  初始化实例阶段不能应用实例的属性
class DropitViewController: UIViewController,UIDynamicAnimatorDelegate {

    // 显示所有内容的View
    @IBOutlet weak var gameView: BeizePathView!
    
    // 这样初始化的时候会有问题 
    //   var animator = UIDynamicAnimator(referenceView: gameView)
    //   这行代码执行在初始化阶段 不能引用实例的属性  等实例初始化完成后才能引用实例的属性
    
    // 一种方法是:在这里设成nil 在viewDidLoad 中执行初始化
    // 另一种是: 将属性设成lazy 并用闭包初始化它
    lazy var animator:UIDynamicAnimator
    /*这个类型必须制定,估计是:使用闭包进行初始化时,不能使用类型推断 要指定其类型*/
    = {
        let $ = UIDynamicAnimator(referenceView: self.gameView)
        $.delegate = self
        return $
    }()
}
上一篇下一篇

猜你喜欢

热点阅读