swift学习 (数据类型+函数和闭包)

作者: 原味丿丿咖啡Vitas | 来源:发表于2016-11-21 20:46 被阅读0次

    无意间看到自己以前学习swift的笔记,从近两年苹果的发布会,可以看出苹果推动swift的决心,OC更换为swift也是未来发展的趋势,想起当初自己钻研学习swift的痛苦的情景,现在把它们整理出来并与现在最新的swift结合以供初学者使用,让初学者少走弯路。有时间会陆续整理后面知识的学习笔记。


    字符串

    字符串介绍
    • String 是一个结构体
    • String 的性能比 NSString 的性能要高
    • String 目前具有了绝大多数 NSString 的功能
    • String 和 NSString 可以无缝转换
    • 在 Swift 中绝大多数的情况下,推荐使用 String 类型
    字符串定义
    • 用 var 定义一个可变字符串
    • 用 let 定义一个不可变的字符串

    //定义一个空的字符串

    let str = ""
    let str1 = String()
    

    //定义字符串并赋初值

    let str3 = "hello world"
    

    //用 var 定义可变字符串,用 let 定义不可变字符串

    var mutableStr = "string can be changed"
    

    //删除第一个字符 s

    mutableStr.remove(at: mutableStr.startIndex)
    print(mutableStr)
    
    字符串拼接

    字符串拼接可以真接用加号
    //: 字符串拼接

    let ustr = "hello, world"
    let ustr2 = "I hove you"
    

    //连接字符串可以直接用 + 和 +=

    var ustr3 = ustr + ustr2
    ustr3 += "very good"
    

    //如果拼接的字符串为可选值

    var ostr: String?
    ustr3 += ostr ?? "no value"
    

    //字符串和变量拼接

    var name = "老王"
    let str6 = "他正准备打开家门,发现 \\(name)从里面出来了"
    

    //: 字符串的格式化
    //妈妈再也不用担心我用 stringWithFormat

    let strb = "字符串\(stra)连接整型\(a)和浮点型\(f)"
    var h = 5
    var m = 6
    var s = 3
    let time = String(format: "%02d:%02d:%02d", h, m , s)
    let time1 = String(format: "%02d:%02d:%02d",arguments: [h, m , s])
    
    字符串比较

    swift 中用 == 和 != 来比较两个字符串
    oc 中用 equalToString 来比较两个字符串
    //比较字符串

    let cstr = "hello"
    let cstr2 = "world"
    let cstr3 = "hello"
    if cstr == cstr3 {
    print("相等")
    }
    if cstr2 != cstr3 {
    print("不相等")
    }
    
    判断前后缀
    var str7 = "ni hao ma"
    let count = str7.utf8.count
    let prefix = str7.hasPrefix("ni")
    let suffix = str7.hasSuffix("ma")
    

    数组

    //数组的创建
    //用var创建一个可变的数组, 用let创建一个不可变的数组

    var array = ["dog", "cat", "pig"]
    var emptyArr: [String] = []
    array.append("fish")
    

    //用初始化的方式, 来创建数组, 一定要指定类型

    var array2: [String] = Array()
    

    //数组的遍历

    for item in array {
    print(item)
    }
    

    //遍历同时拿到index

    for item in array.enumerated() {
    print("\(item.offset): \(item.element)")
    

    }

    //倒序遍历

    for item in array.reversed() {
    print(item)
    }
    

    //数组的操作
    //数组的合并

    var array3 = ["goat", "snake"]
    var array4 = ["dog", "cat", "pig"]
    var array5 = array3 + array4
    

    //删除元素

    let removed = array5.remove(at: 0)
    

    //修改

    array5[0] = "sheep"
    

    //和oc的数组互转

    let ocArray = array5 as NSArray
    ocArray.subarray(with: NSMakeRange(0, 3))
    

    字典

    //定义一个字典
    //用var定义一个可变的字典, 用let定义一个不可变的字典

    var dict = ["first": "dog", "second": "cat"]
    

    //定义一个空的字典

    var dict1: [String: String] = Dictionary()
    var dict2: [String: String] = [:]
    

    //遍历字典

    for (k, v) in dict {
    print("key: \(k), value: \(v)")
    }
    

    //字典的操作, 增删查改, 字典的操作都是围绕key值做操作

    //增

    dict["third"] = "pig"
    

    //删

    dict["second"] = nil
    

    //查:从字典中取出的值,是一个可选值, 使用的时候最好做一次可选绑定

    let first = dict["first"]
    

    //改

    dict["first"] = "duck"
    print(dict)
    

    函数

    //用func创建一个函数
    //函数名后面接小括号, 小括号不能省略
    //小括号里面放参数, 参数必须指定类型, 多个参数用逗号隔开
    //如果没有返回值, 返回值的部分可以省略

    func add(a: Int, b: Int) -> Int {
    return a + b
    }
    

    //函数没有返回值,本质上返回一个空的元组

    func addOne(a: Int, b: Int) {
    print(a + b)
    }
    
    func addTwo(a: Int, b: Int) -> () {
    print(a + b)
    }
    
    func addThree(a: Int, b: Int) -> Void {
    print(a + b)
    }
    

    //没有参数,没有返回值

    func methodOne () {
    print("hello, class seven")
    }
    
    methodOne()
    

    //有参数, 没有返回值
    func methodTwo (a: Int, b: Int) {
    print(a + b)
    }
    methodTwo(a: 5, b: 5)
    //有参数有返回值, 返回的值和返回值类型必须保持一至

    func methodThree (a: Int, b: Int) -> Int {
    return a + b
    }
    
    let result = methodThree(a: 5, b: 5)
    
    let method = methodTwo
    

    函数的参数

    //默认情况下, swift会给每个参数加一个和形参一样的外部参数名
    //外部参数名, 就是对参数做解释说明的字符串
    //外部参数名, 在调用的时候, 必须写

    func add(a: Int, b: Int) -> Int {
    return a + b
    }
    
    add(a: 5, b: 10)
    

    //也可以自定义外部参数名

    func addOne(first a: Int,second b: Int) -> Int {
    return a + b
    }
    addOne(first: 5, second: 10)
    

    //也可以忽略外部参数名
    //使用忽略运算符忽略外部参数名

    func addTwo(_ a: Int,_ b: Int) -> Int {
    return a + b
    }
    addTwo(5, 10)
    

    函数的默认参数

    //swift语言函数的参数可以设默认值
    //如果参数有默认值,则该参数可传可不传

    func add(a: Int, b: Int = 10) -> Int {
    return a + b
    }
    
    add(a: 5)
    add(a: 5, b: 156)
    
     func customLabel (title: String, fontSize: CGFloat = 13,   alignment: NSTextAlignment = .left, numerOfLines: Int = 0) -> UILabel {
    let label = UILabel()
    label.text = title
    label.font = UIFont.systemFont(ofSize: fontSize)
    label.textAlignment = alignment
    label.numberOfLines = numerOfLines
    
        return label
    }
    
    let label0 = customLabel(title: "label", fontSize: 13, alignment: .left, numerOfLines: 0)
    
    let lable = customLabel(title: "label")
    

    闭包

    //闭包是一个匿名的函数块
    //闭包被完整地包裹在大括号里面
    //闭包的调用方式和函数一样
    //闭包可以做为参数传递,也可以做为返回值返回

    //没有参数,没有返回值

    func methodOne () {
    print("hello, class seven")
    }
    
    methodOne()
    

    //有参数, 没有返回值

    func methodTwo (a: Int, b: Int) {
    print(a + b)
    }
    methodTwo(a: 5, b: 5)
    //有参数有返回值, 返回的值和返回值类型必须保持一至
    func methodThree (a: Int, b: Int) -> Int {
    return a + b
    }    
    
    闭包的定义和调用
    //没有参数,没有返回值的闭包
    let clousureOne = {
    print("hello, class seven, seven")
    }
    
    clousureOne()
    
     //有参数, 没有返回值
    //参数和执行语句都写在大括号里面, 用in隔开
    //闭包没有外部参数名
    let clousureTwo = {
    (a: Int, b: Int) in
    print(a + b)
    }
    
    clousureTwo(5, 12)
    
    //有参数, 有返回值
    let clousureThree = {
    (a: Int, b: Int) -> Int in
    return a + b
    }
    
    let result = clousureThree(5, 240)
    

    闭包的使用

    需求::

    下载一部 av, 完成后更新 UI 提示, 要求用闭包实现
    实现::

    1. 新建一个函数,实现下载的功能
    2. 新建一个闭包,更新 ui
    3. 将闭包作为函数传递,下载成功后,下载函数中调用更新 UI 的闭包,功能实现

    class ViewController: UIViewController {

    var activity: UIActivityIndicatorView?
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        let label = UILabel(frame: CGRect(x: 20, y: 40, width: 400, height: 30))
        self.view.addSubview(label)
    
        activity = UIActivityIndicatorView(activityIndicatorStyle: .Gray)
        self.view.addSubview(activity!)
        activity!.center = self.view.center
    
        let downloadAVFinished = {
            (money:  String) in
            print(money)
            label.text = "我下载了了\(money)rmvb,快来和我做朋友吧"
        }
    
        dowloadAV(downloadAVFinished)
    
        activity!.startAnimating()
    }
    
    func dowloadAV (block: (String)->()) {
    
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { () -> Void in
    
            let time: NSTimeInterval = 3
            let delay = dispatch_time(DISPATCH_TIME_NOW, Int64(time*Double(NSEC_PER_SEC)))
            dispatch_after(delay, dispatch_get_main_queue()) { () -> Void in
                let av = "苍井空"
                block(av)
                self.activity!.stopAnimating()
            }
        }
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    }
    

    尾随闭包

    • 如果闭包代码块作为函数的最后一个参数
    • 当函数调用时,可以将闭包代码块写在参数的小括号的外面
    • 尾随闭包可以增强函数的可读性
    • 注意: 如果函数只需要闭包表达式一个参数,当您使用尾随闭包时,您甚至可以把()省略掉。
    //定义一个闭包
    let closure = {
    (a: Int) -> Int in 
    return a + 5
    }
    
        //定义一个函数,第二个参数为闭包
    func method (a: Int, sum: (Int)->(Int))->Int{
    return sum(a)    
    }
    
    //调用函数
    func(5, closure)
    
    //上面的调用等同于,直接将闭包代码块作为参数传入
    func(5, {
    (a: Int) -> Int in 
    return a + 5
    })
    
    //将闭包写在括号外面
    func (5){
    (a: Int) -> Int in 
    return a + 5
    }
    

    闭包的循环引用

    循环引用的场景
    • 当 self 中强引用了闭包,而闭包中又使用了 self 时,会发生循环引用
    • 循环引用的三种解决方法
    1. 使用 oc 的 weakself 的写法
      weak 的对象在运行时,有可能被设为 nil, 所以只能用 var, 且是可选的
      weak var weakself = self
      downloadBlock = {
      (money: String) in
      print(money)
      weakself!.textLabel!.text = "我下载了了(money)rmvb,快来和我做朋友吧"
      print("======(self)")
      }

    2.使用 swfit 的 weakself 的写法
    [weak self] 表示闭包中的 self 是弱引用,在运行时可能被设为 nil,所以闭包中的 self 也是可选的

        downloadBlock = {
            [weak self] (money:  String) in
            print(money)
            self!.textLabel!.text = "我下载了了\(money)rmvb,快来和我做朋友吧"
            print("======\(self)")
    

    3.使用 swift 中的 unknown
    [unowned self] 和弱引用不同的是,unowned 引用是永远有值的。因此,unowned 总是被定义为不可选;
    如果 self 释放,会产生野指针
    使用的情况是 self 永远不需要释放

        downloadBlock = {
            [weak self] (money:  String) in
            print(money)
            self!.textLabel!.text = "我下载了了\(money)rmvb,快来和我做朋友吧"
            print("======\(self)")

    相关文章

      网友评论

        本文标题:swift学习 (数据类型+函数和闭包)

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