当前位置: 首页>移动开发>正文

swift Podfile内容格式 swift api文档

一. 将Protocol的方法声明为mutating
Swift的协议不仅可以被class类型实现,也适用于struct和enum, 因为这个原因在写给别人用的协议时需要考虑是否使用mutating来修饰方法,这个关键字修饰方法是为了能在该方法中国修改struct和enum的变量,“所以如果你没在协议方法里写 mutating 的话,别人如果用 struct 或者 enum 来实现这个协议的话,就不能在方法里改变自己的变量了”。
在使用class来实现带有mutating的方法协议,具体实现的方法前面不需要加mutating的修饰。

二. Sequence Swift 的for in 可以用在所有实现了Sequence的类型上,而为了实现Sequence首先需要实现一个IteratorProtocol。

//首先定义一个实现了IteratorProtocol 的class
class ReverseIterator<T>: IteratorProtocol {
    //IteratorProtocol需要指定一个typealias Element
    typealias Element = T
    var array: [Element]
    var currentIndex = 0
    
    init(array: [Element]) {
        self.array = array
        currentIndex = array.count - 1
    }
    
    //提供一个返回Element?的方法 next()
    func next() -> T? {
        if currentIndex < 0{
            return nil
        } else {
            let element = array[currentIndex]
            currentIndex -= 1
            return element
        }
    }
}

//其次需要顶一个一个继承Sequence 的class
struct ReverseSequence<T>: Sequence {
    //和 IteratorProtocol 很类似,不过换成指定一个 typealias
    typealias Iterator = ReverseIterator<T>
    
    var array: [T]
    init(array: [T]) {
        self.array = array
    }
    
    //提供一个返回ReverseIterator的makeIterator
    func makeIterator() -> ReverseIterator<T> {
        return ReverseIterator(array: self.array)
    }
}

复制代码

在如下使用:

var arr = [10, 11, 12, 13, 14]
 for (i, _) in ReverseSequence.init(array: arr).enumerated() {
            print("Index\(i) is \(arr[i])")
 }
 
复制代码

三. 多元组
swift中,返回值可以包含多个值。

四. @autoclosure ??
在swift中对闭包的用法可以进行一些简写如

logIfTrue({return 2 > 1})  写成   logIfTrue({2 > 1})
复制代码

autoclosure就是把一句表达式自动的封装成一个闭包如下:

func logIfTrue(_ predicate:@autoclosure () -> Bool) {
   if predicate() {
       print(true)
    }
 }
复制代码

在使用的时候只需要写 logIfTrue(2 > 1),连{}都可以省略。swift会把2 > 1这个表达式自动转换成() -> Bool。

在Swift中,有一个非常有用的操作符 ?? 。可以用来快速地对nil进行条件判断,一个对象在使用??的时候,如Int类型,实际上会被封装成一个 () -> Int

func ??<T>(optional: T?, defaultValue: @autoclosure () -> T) -> T {
     switch optional {
     case .Some(let value):
          return value
      case .None:
        return defaultValue()
      }
 }
复制代码

在这里使用了一个autoclosure 包了一个() -> T,没有autoclosure就不需要在??操作符真正取值之前就需要准备一个默认值传入到这个方法中,实际上我们没有用到这个默认值,而会直接返回optional解包后的值,这样就避免了不必要的开销,方法就是将默认值的计算推迟到optional判定为nil之后。这样就可以很优雅的写法处理对optional及默认值的取值了。
@ autoclosure并不支持带有输入参数的写法。

五. @escaping

func doWorkAsync(block: @escaping ()->()) {
        DispatchQueue.main.async {
            block()
        }
    }
复制代码

在闭包前加上@escaping来标明这个闭包是会逃逸出这个方法的。如果在父类或者协议中定义了一个接受@escaping为参数的方法,那么在协议的实现或子类中,也同样需要加上@escaping,否则会被认为是不同的方法。

六. 字面量表达
swift提供了一组非常有意思的协议,使用字面量来表达特定的类型,那些实现了字面量表达协议的类型,在赋值的时候就可以简单地按照协议方法中定义的规则“无缝对应”地通过赋值的方式将值表达为对应类型,实际开发中用到的字面量协议:

ExpressibleByArrayLiteral
ExpressibleByBooleanLiteral
ExpressibleByDictionaryLiteral
ExpressibleByFloatLiteral
ExpressibleByNilLiteral
ExpressibleByNilLiteral
复制代码

所有的字面量都定义了一个typealias和对应的init方法。

七. 初始方法顺序
与Objc不同的是,Swift的初始方法需要保证类型的所有属性都被初始化完成之后才调用父类的初始化方法。最后如果有需要,对父类的需要改变的属性进行重新赋值。 值得注意的是在swift中可以对let 声明的常量进行赋值。

八. default参数
swift的方法是支持默认参数的,即在声明方法的时候可以给参数一个默认的值,NSLocalizedString就是其中这样使用的例子。

func sayHello1(str1: String = "Hello", str2: String, str3: String) {
    print(str1 + str2 + str3)
}
复制代码

九. AnyClass,元类型和 .self
通过AnyObject.Type这种方法得到的是一个元类型(Meta),A.Type代表的是A类型的类型。

class A {
}

let typeA: A.Type = A.self
复制代码

.self可以用在类型后面取得类型本身,例如我们经常会在register cell的class的时候会用到这个元类型。

十.属性观察
属性观察 (Property Observers) 是 Swift 中一个很特殊的特性,利用属性观察我们可以在当前类型内监视对于属性的设定,并作出一些响应。Swift 中为我们提供了两个属性观察的方法,它们分别是 willSet 和 didSet。

var date: NSDate {
    willSet {
        let d = date
        print("即将将日期从 \(d) 设定至 \(newValue)")
    }
    
    didSet {
        print("已经将日期从 \(oldValue) 设定至 \(date)")
    }
}
复制代码

值得注意的是,计算属性和观察属性是不能共存的。

十一. Optional Map
在swift中可以对Array使用Map的操作,这个方法能对数组中的所有元素应用某一种规则,我们可以在CollectionType(Array遵守了这个协议)的Extension中找到关于这个方法的定义:

extension CollectionType {
    public func map<T>(@noescape transform: 
                    (Self.Generator.Element) -> T) -> [T]
}

复制代码

从上面的代码可以看出swift中支持协议的扩展。而同样地Optional也有一个类似的map:

public enum Optional<T> : _Reflectable, NilLiteralConvertible {
    /// If `self == nil`, returns `nil`.  Otherwise, returns `f(self!)`.
    public func map<U>(@noescape f: (T) -> U) -> U?

}
复制代码

这个方法很方便地对一个optional值做变化和操作,不比进行手动的解包工作。输入会被自动用类似Optinal Binding 的方式进行判断。这些都符合函子(Functor)的概念。

十二. Swift命令行工具
直接使用swift 可以执行.swift的文件,可以通过swift --help,swiftc --help查看,Swift命令行工具的另一个常用的地方就是直接脱离Xcode环境进行编译和生成可执行文件。

swiftc -O test.swift -o test..asm
复制代码

十三. Filter
常见操作是检查一个数组,然后将这个数组中符合一定条件的元素过滤出来并用它们创建一个新的数组

let nums = [2,4,5,6,7,8,9,10]
let filers = nums.filter { extension Array {
    func filter(_ isIncluded: (Element) -> Bool) -> [Element] {
        var result: [Element] = []
        for x in self where isIncluded(x) {
            result.append(x)
        }
        return result
    }
}
复制代码 % 2 == 0 }
print(filers)
复制代码

swift中Array和Dictionary中的每一个元素可以用$0来简写,通过组合map 和 filter,我们现在可以轻易完成很多数组操作,而不需要引入中间数组。

filter的实现看起来和map很类似:

contains

如果只是想要查找数组中是否有满足条件的元素,从性能上讲就大可不必用filter,而是可以使用let total = nums.reduce(0, +) 复制代码,一般来讲当我们需要所有结果的时候才去使用filter。

十四. reduce
map和filter都作用在数组上,并产生一个新的、修改过的数组,不过有可能你想要把所有新的元素组合成一个新的值。

extension Array {
    func reduce<Result>(_ initialResult: Result,
                        _ nextPartialResult: (Result, Element) -> Result) -> Result
    {
        var result = initialResult
        for x in self {
            result = nextPartialResult(result, x)
        }
        return result
    }
}
复制代码

如下是reduce的实现:

十五. 集合类型协议
1. 序列
Sequence协议是集合类型协议的基础,一个序列代表的是一系列具有相同类型的值,遍历一个序列最简单的方式就是for循环。满足Sequence协议十分简单,就是提供一个返回迭代器的makeIterator() 方法,如最开始的例子。 2.集合类型
集合类型 (Collection) 指的是那些稳定的序列,它们能够被多次遍历且保持一致。Collection协议是简历在Sequence之上,除了从Sequence继承了所有的方法,集合还提供了新的功能如count。



https://www.xamrdz.com/mobile/42j1959889.html

相关文章: