美文网首页Swift_Learn程序员@IT·互联网
三日上手swift(最后一天)会陆续更新到项目

三日上手swift(最后一天)会陆续更新到项目

作者: 子祖 | 来源:发表于2016-08-18 11:23 被阅读453次

    本swift教程并不是教大家如何如何玩转一门语言,是让大家快速看懂别人swfit的项目,最后加上强大的复制粘贴和万能的google,用一种相对极端的方法快速入门做项目



    重复说明,我的写代码,大家千万不要拿去敲(谁敲谁傻b),太浪费时间和消磨积极性,只需要根据代码板块复制粘贴到playground上看(不知道的看上一篇文章), 一块一块看比较有效率 ,特别要看打印结果,然后可以自己根据思路写上注释,如果遇到报错,可能是你复制粘贴代码导致重复定义,也可能是xcode的问题,细节不用太在意,主要了解语法结构!

    重点到最后一章我会上传一个小项目让你大家来敲一遍,敲到不懂的回来看即可!


    循环引用
    import UIKit
    
    class Person {
        var book : Book?
    
        deinit {
            print("Person -- 销毁")
        }
    }
    
    class Book {
        weak var owner : Person?//解决循环引用,指向的对象销毁时,会自动指向nil,所用用Var(因为可选类型)
    
        deinit {
            print("Book -- 销毁")
        }
    }
    
    var p : Person? = Person()
    var b : Book? = Book()
    
    p!.book = b
    b!.owner = p
    
    p = nil
    b = nil
    
    可选链

    可选链的使用:赋值、取值、调用方法,里面系统会自己判断可选类型,且进行

    解绑
    赋值:
    person.dog?.toy?.price = 50
    取值:
    let price = person.dog?.toy?.price
    调用方法
    person.dog?.toy?.flying()
    
    import UIKit
    
    // 1.声明类
    class Person {
        var name : String = ""
        var dog : Dog?
    }
    
    class Dog {
        var weight : Double = 0.0
        var toy : Toy?
    }
    
    class Toy {
        var price : Double = 0.0
    
        func flying() {
            print("飞盘在flying")
        }
    }
    
    // 2.创建类对应的对象
    let person = Person()
    person.name = "Kobe"
    
    let dog = Dog()
    dog.weight = 30.0
    
    let toy = Toy()
    toy.price = 100.0
    
    // 3.让三个对象之间产生关系
    person.dog = dog
    dog.toy = toy
    
    // 4.可选链的使用
    // 4.1.将person的dog的toy的价格修改成50
    // 给可选链进行赋值
    // person.dog!.toy!.price = 50 太危险
    /* 太麻烦
    if let dog = person.dog {
        if let toy = dog.toy {
            toy.price = 50
        }
    }
     */
    person.dog?.toy?.price = 50
    
    // 4.2.取出person的dog的toy的价格
    // 从可选链取值 : 从可选链中取值取到的类型一定是一个可选类型
    //let price = person.dog!.toy!.price
    /*
    if let dog = person.dog {
        if let toy = dog.toy {
            let price = toy.price
        }
    }
     */
    let price = person.dog?.toy?.price
    
    // 4.3.让person的dog的toy的飞起来
    // 可选链调用方法 : 系统会自动判断可选类型是否有值
    // person.dog!.toy!.flying()
    person.dog?.toy?.flying()
    

    协议:

    用协议来实现多继承,但oc、swift本事不支持多继承

    // 1.如何定义协议
    protocol SportProtocol {
        func playBasketball()
        func playFootball()
    }
    
    // 2.声明类, 并且遵守协议
    class Person : SportProtocol {
        var name : String = ""
    
        func playBasketball() {
            print("打篮球")
        }
    
        func playFootball() {
            print("踢足球")
        }
    }
    
    //逗号分隔遵守多个协议
    class Dog : NSObject, SportProtocol {
        func playBasketball() {
            print("打篮球")
        }
    
        func playFootball() {
            print("踢足球")
        }
    }
    
    基协议
    import UIKit
    
    // NSObjectProtocol : Swift中基协议
    
    protocol CrazySportProtocol : NSObjectProtocol {
        func jumping()
    }
    
    protocol SportProtocol : CrazySportProtocol {
        func playBasketball()
    }
    
    class Person: NSObject, SportProtocol {
        func playBasketball() {
            print("打篮球")
        }
    
        func jumping() {
            print("蹦极")
        }
    }
    
    @objc : 可以保留OC某些特性
    import UIKit
    
    // @objc : 可以保留OC某些特性(可选性)
    @objc protocol SportProtocol {
        func playBasketball()
        func playFootball()
    
        optional func jumping()
    }
    
    class Person: SportProtocol {
        @objc func playBasketball() {
    
        }
    
        @objc func playFootball() {
    
        }
    
        @objc func jumping() {
    
        }
    }
    
    协议在设计代理模式中的应用
    import UIKit
    
    // 1.定义协议 : 规范
    // class --> 该协议只能被类遵守
    
    protocol BuyTicketDelegate : class {
        func buyTicket() -> String
    }
    
    // 2.定义类, 并且有一个去北京的行为
    class Person {
        var name : String = ""
        weak var delegate : BuyTicketDelegate?
    
        func goToBeijing() {
    
            // print("买火车票")
            // 让代理帮你买票
            let ticket = delegate?.buyTicket()
            print(ticket)
    
            print("坐火车去北京")
        }
    }
    
    // 3.创建对象
    let p = Person()
    p.name = "Kobe"
    
    // 4.定义其他类, 遵守协议, 并且有买票的行为
    class YellowCatte : BuyTicketDelegate {
        func buyTicket() -> String {
            return "从广州到北京的高铁"
        }
    }
    
    class Student: BuyTicketDelegate {
        func buyTicket() -> String {
            return "帮助同学买了一张票"
        }
    }
    
    // 5.创建具体的对象,成为person的代理
    let huangNiu = YellowCatte()
    p.delegate = huangNiu
    
    // 6.去北京
    p.goToBeijing()
    

    闭包(其实就是oc中的block)

    基本写法:(参数列表)-> (返回值类型)

    建一个HttpTools类,内部如下

    import UIKit
    
    class HttpTools {
        // (参数列表) -> (返回值类型)
        func loadData(finishedCallback : (result : String) -> ()) {
            dispatch_async(dispatch_get_global_queue(0, 0)) {
                print("发送异步网络请求:\\\\(NSThread.currentThread())")
    
                dispatch_sync(dispatch_get_main_queue(), {
                    print("回调主线程:\\\\(NSThread.currentThread())")
    
                    finishedCallback(result: "json数据")
                })
            }
        }
    
    }
    
    ViewController中使用
    import UIKit
    
    class ViewController: UIViewController {
    
        var tools : HttpTools?
    
        // override : 对父类方法的重写
        override func viewDidLoad() {
            super.viewDidLoad()
    
            tools = HttpTools()
        }
    
        override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
            tools?.loadData({ (result) in
                print("在ViewController中获取到数据:\\\\(result)")
            })
        }
    }
    
    尾随闭包,可对比上面的代码
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
            // 尾随闭包 : 如果函数的最后一个参数是一个闭包.那么可以将函数调用写成尾随闭包
            tools?.loadData() { (result) in
                print("在ViewController中获取到数据:\\\\(result)")
            }
    
            // 如果函数有且只有一个参数,并且是一个闭包, 那么()也可以省略
            tools?.loadData { (result) in
                print("在ViewController中获取到数据:\\\\(result)")
            }
        }
    
    闭包的循环引用

    循环引用解决方案二:(推荐)
    tools?.loadData({[weak self] (result) in
    self?.view.backgroundColor = UIColor.redColor()
    })

    import UIKit
    
    class ViewController: UIViewController {
    
        var tools : HttpTools?
    
        // override : 对父类方法的重写
        override func viewDidLoad() {
            super.viewDidLoad()
    
            tools = HttpTools()
        }
    
        override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    
            // 如果是在闭包中用到当前对象属性或者方法时,self也不可以省略
            // weak : 指向的对象销毁时,会自动指向nil
    
            // 循环引用解决方案一:
            /*
            weak var weakself : ViewController? = self
            tools?.loadData({ (result) in
                // print("在ViewController中获取到数据:\\\\(result)")
                weakself?.view.backgroundColor = UIColor.redColor()
            })
            */
    
            // 循环引用解决方案二:(推荐)
            /*
            tools?.loadData({[weak self] (result) in
                self?.view.backgroundColor = UIColor.redColor()
            })
            */
    
            // 循环引用解决方案三:(不推荐)
            tools?.loadData({[unowned self] (result) in
                self.view.backgroundColor = UIColor.redColor()
            })
        }
    
        deinit {
            print("ViewController -- deinit")
        }
    }
    

    懒加载

    import UIKit
    
    /*
     用到时再加载
     多次使用只会加载一次
     */
    
    class ViewController: UIViewController {
    
        lazy var names : [String] = {
            return ["Kobe", "James", "Curry"]
    
        }()
    
        //这种写法可带参数
        lazy var btn : UIButton = {
            let btn = UIButton()
            btn.setTitle("按钮", forState: .Normal)
            btn.backgroundColor = UIColor.redColor()
    
            return btn
    
        }()
    
        //这种写法不可带参数,但比较简便,方便使用
        lazy var btn1 : UIButton = UIButton()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // print(names.count)
    
        }
    
        override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
            names.count
        }
    }
    

    访问权限:

    internal : 内部的
    1> 当不指定具体的访问权限时, 默认的访问权限就是internal
    2> internal的访问权限: 在当前项目(包)的任何地方都可以访问

    private : 私有的
    private的访问权限 : 在当前的源文件中可以访问

    public : 公共的
    1> public的访问权限 : 可以跨包进行访问
    2> 包 : 项目/框架

    处理异常

    主要看方式二: try?方式 --> 系统处理异常, 如果有异常,则返回nil,如果没有异常,则返回结果
    let regex = try? NSRegularExpression(pattern: "", options: .CaseInsensitive)
    regex?.matchesInString("", options: [], range: NSMakeRange(0, 0))

    // 创建一个`正则表达式`对象
            // let view = UIView(frame: CGRectZero)
    
            // 在swift中如果在调用一个方法, 该方法最后一个throws, 那么说明该方法会抛出异常
            // 如果该方法有抛出异常,必须对异常进行处理. 如果不处理,则编译不通过
            /*
             三种处理异常的方式
               方式一: try方式 --> 手动处理异常, 并且可以获取到最终的异常结果
                 do {
                    let regex = try NSRegularExpression(pattern: "", options: .CaseInsensitive)
                 } catch {
                    print(error)
                 }
               方式二: try?方式 --> 系统处理异常, 如果有异常,则返回nil,如果没有异常,则返回结果
                 let regex = try? NSRegularExpression(pattern: "", options: .CaseInsensitive)
                 regex?.matchesInString("", options: [], range: NSMakeRange(0, 0))
             方式三: try!方式(不推荐) --> 告诉系统该方法不可能有异常. 注意:一旦发生异常,程序就会崩溃
                let regex = try! NSRegularExpression(pattern: "", options: .CaseInsensitive)
            */
    
    自定义抛出异常
    import UIKit
    //异常要用枚举,且继承ErrorType
    enum TypeError : ErrorType {
        case Jian1
        case Jian2
        case Jian3
        case TooBig
    }
    
    class HttpTools: NSObject {
        func loadData(type : Int) throws -> String {
            switch type {
            case 0:
                return "zero"
            case 1:
                return "one"
            case 2:
                return "two"
            case 3:
                // 抛出异常
                throw TypeError.Jian1
            case 4:
                // 抛出异常
                throw TypeError.Jian2
            case 5:
                // 抛出异常
                throw TypeError.Jian3
            default:
                // 抛出异常
                throw TypeError.TooBig
            }
        }
    }
    

    相关文章

      网友评论

      • changbenhe:已看完!非常不错!谢谢 :+1:
      • 春泥Fu:帅哥~ 讲真啦,oc转swift大概要多久,想转swift~~~~
        子祖:@春泥Fu 因为api和方法名都是一样的
        春泥Fu:@子祖 :fist: 好! 我试试~
        子祖:@春泥Fu 其实语言根本不是个什么问题,真的就是三天,建议你看完这个直接找个项目对着抄

      本文标题:三日上手swift(最后一天)会陆续更新到项目

      本文链接:https://www.haomeiwen.com/subject/urkvsttx.html