Swift基础知识

作者: 懒得起名的伊凡 | 来源:发表于2015-09-14 15:29 被阅读92次

    autoclosure

    @autoclosure 做的事情就是把一句表达式自动地封装成一个闭包。用法就是在类型签名加上@autoclosure关键字,类似??的实现

    public func ??<T>(optional: T?, defaultValue: @autoclosure () throws -> T) rethrows -> T
    

    Note:
    @autoclosure不支持带有输入参数的写法,也就是说只有类似() -> T的参数才能使用这个特性进行简化。

    escaping

    Swift3中,闭包默认是@noescape的,这个不需要写出来,会报错。

    func doWork(block: () -> ()){
        block()
    }
    

    也就是说,该闭包的生命周期不能超过doWork,也不能被doWork中的其他闭包捕获(也就是强持有)。

    Note

    • 需要注意使用时的内存问题
    • 在协议或者父类中定义了一个接受@escaping为参数方法,那么在实现协议和这个父类的子类中,对应的方法必须被声明为@escaping,否则两个方法会被认为拥有不同的函数签名。

    操作符的重载

    Swift支持重载操作符的操作,Objective-C不支持

    定义一个新的操作符

    下标

    extension Array{
        subscript(input: [Int]) -> ArraySlice<Element>{
            get{
                var result = ArraySlice<Element>()
                for i in input{
                    assert(i < self.count,"Index (\(i)) out of range")
                    result.append(self[i])
                }
                
                return result
            }
            set{
                for (index,i) in input.enumerated(){
                    assert(i < self.count,"Index (\(i)) out of range")
                    self[i] = newValue[index]
                }
            }
        }
    }
    
    var arr = [1,2,3,4,5] //[1, 2, 3, 4, 5]
    
    arr[[1,3]]//[2, 4]
    
    arr[[1,4]] = [9,8]//[9, 8]
    
    arr//[1, 9, 3, 4, 8]
    
    • 类型别名

    类型别名就是给现有类型定义另一个名字。可以使用 typealias 关键字类定义类型别名

    • 关于nil的解释

    在Objective-C中,nil是一个指向不存在对象的指针。在Swift中,nil不是指针,他是一个确定的值,用来表示值的缺失。任何类型的可选状态都可以被设置为nil,不只是对象类型。

    • 强制解析可选类型 !

    如果确定可选类型确实包含值之后,可在可选的名字后面加一个感叹号(!)来获取值。

    • 隐式解析可选类型

      把想要用作可选的类型的后面的问号(?)改成感叹号(!)来声明一个隐式解析可选类型。一个隐式解析可选类型其实就是一个普通的可选类型,但是可以被当做非可选类型来使用,不需要每次都是用解析来获取可选值。

    注意:如果一个变量之后可能变成nil的话,不要使用隐式解析可选类型。

    • 错误处理

    一个函数可以在声明中添加 throws 关键字来抛出错误消息。
    func canThrowAnError() throws{
    //do somthing
    }
    当函数能够抛出错误消息时,应该在表达式中前置 try 关键字
    do{
    try canThrowAnError()
    //没有错误消息抛出,继续执行
    }
    catch condition1{
    //第一种错误方式处理
    }
    catch condition2{
    //第二种错误方式处理
    }

    • 断言(assert)

    使用场景:
    在某些情况下,如果值缺失或者不满足特定的条件,代码可能无法继续执行。这时可在代码中触发一个断言来结束代码运行并通过调试来找到值缺失的原因。

    触发条件:
    如果判定条件为 true,代码会继续进行。否则,若判断条件为false,代码运行停止,应用也会被终止。

    如:
    let age = -3
    assert(age > 0,"A person's age cannot be less than zero")

    注:当条件可能为假时使用断言,但最终一定要保证条件为真。

    • 字符串的用法
      1、计算字符串中字符的数量
      let unusualMenagerie = "Koala 🐨, Snail 🐌, Penguin 🐧, Dromedary 🐪"
      print("unusualMenagerie has (unusualMenagerie.characters.count) characters")
      2、字符串的索引
      使用startIndex 属性获取字符串的第一个Character的索引。
      使用endIndex 属性获取最后一个Character的后一个位置索引(值与字符串的长度相同)。
      使用 predecessor()方法,得到前面的一个索引。
      使用successor() 方法,得到后面的一个索引。
      任何一个String的索引都可以通过锁链作用的这些方法来获取另一个索引,也可调用advancedBy(:)方法来获取。
      可使用characters属性的indices属性创建一个包含全部索引的范围(Range)
      var str = "Hello, playground"
      for index in str.characters.indices{
      print("(str[index])")
      }
      3、插入和删除
      调用insert(
      :atIndex:)方法可以在一个字符串的指定索引插入一个字符。
      var welcome = "hello"
      welcome.insert("!", atIndex: welcome.endIndex)
      // welcome now 现在等于 "hello!"
      调用insertContentsOf(:at:)方法可以在一个字符串的指定索引插入一个字符串。
      welcome.insertContentsOf(" there".characters, at: welcome.endIndex.predecessor())
      // welcome 现在等于 "hello there!"
      调用removeAtIndex(
      :)方法可以在一个字符串的指定索引删除一个字符。
      welcome.removeAtIndex(welcome.endIndex.predecessor())
      // welcome 现在等于 "hello there"
      调用removeRange(_:)方法可以在一个字符串的指定索引删除一个子字符串。
      let range = welcome.endIndex.advancedBy(-6)..<welcome.endIndex
      welcome.removeRange(range)
      // welcome 现在等于 "hello"

    相关文章

      网友评论

        本文标题:Swift基础知识

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