美文网首页
Swift3.0学习(三)

Swift3.0学习(三)

作者: cdd48b9d36e0 | 来源:发表于2018-02-13 15:01 被阅读2次

    1、协议的基本使用

    • 协议可以继承
    • 类、结构体和枚举都可以遵循协议
    • 如果遵循了协议,则必须实现协议里所有的方法

    2、协议的代理使用

    轻量级的时候只需加class

    protocol Work: class {
        func work()
    }
    class Person {
        //只有Work继承于work或者NSObjectProtocol,这里才能用weak
        weak var delegate: Work?
        
        func doWork() {
            // 让别人"打印机" 去打印
            delegate?.work()
        }
    }
    

    更全的时候加NSObjectProtocol

    protocol Work: NSObjectProtocol {
        func work()
    }
    class ColorP: NSObject, Work {
        func work() {
            print("彩色打印机打印")
        }
    }
    

    3、让协议的方法可选(不用实现)

    纯Swift并不提倡这么做,从契约精神上讲遵循协议就应该全部做到里面规定的内容

    @objc
    protocol Work {
       @objc optional func test()
    }
    
    //下面是关键字objc的另一个使用场景
    class pp:NSObject{
        func test(a: Int)  {
        }
        @objc(xxx:)//告诉oc,当在oc里使用时下列方法名为xxx:
        func test(a: Double)  {        
        }
    }
    

    4、泛型

    定义:不是某一种具体的类型,它的类型在传值的时候才会决定

    // 函数
    func exchange<T>(num1: inout T, num2: inout T) {
        
        let temp = num1
        num1 = num2
        num2 = temp
        
    }
    var num1 = "10"
    var num2 = "20"
    //exchange(num1: &num1, num2: &num2)
    exchange(num1: &num1, num2: &num2)
    num1
    num2
    
    // 结构体
    struct Point<T> {
        var x: T
        var y: T
    }
    
    let p = Point(x: 10, y: 10)
    p.x
    
    let p2 = Point(x: 10.1, y: 10.3)
    p2.x
    
    // 类
    class Stack<T> {
        
        var nums: [T] = []
        
        func push(num: T) {
            nums.append(num)
        }
        
        func pop() -> T {
            return nums.removeLast()
        }
        
    }
    
    let st = Stack<String>()
    st.push(num: "10")
    st.push(num: "20")
    st.nums
    st.pop()
    st.pop()
    
    //协议
    protocol Some {
        
        // 协议里面,定义一个泛型, associatedtype
        associatedtype T
        
        func work() -> T
        func eat() -> T
        
    }
    
    
    class Person: Some {
        func work() -> Person {
            print("人工作")
            return self
        }
        func eat() -> Person {
            print("人吃饭")
            return self
        }
        
    }
    
    let p22 = Person()
    p22.work().eat().work().eat().eat().eat().eat()
    
    
    class Dog: Some {
        func work() -> Dog {
            print("🐩工作")
            return self
        }
        func eat() -> Dog {
            print("🐶吃饭")
            return self
        }
        
    }
    
    let d = Dog()
    d.eat().work().eat().eat().eat().eat()
    
    class Stu : Person {
        
        
    }
    
    func test2<T>(a: T) where T: Person {
        
    }
    
    test2(a: Person())
    

    where给泛型加限制条件

    func test2<T>(a: T) where T: Person {
        //这里的意思是泛型T必须是继承于Person类型
    }
    

    5、闭包的基本使用

    var addBlock: (Int, Int) -> (Int) = {
        (a:Int,b:Int) -> (Int) in
        
        return a + b
        
    }
    addBlock(12, 12)
    

    如果闭包参数是空,可以省略in和in前面的内容

    var simpleBibao: () -> (Int) = {
        print("test")
        return 10
    }
    

    6、三种闭包

    • 参数闭包
    • 尾随闭包:当设计一个函数,其内部需要接收闭包,一定要注意尽量把闭包类型的参数放最后
    • 逃逸闭包:如果一个函数的参数,是一个闭包类型,那么默认情况下,是一个“非逃逸”的闭包(闭包,生命周期,是函数)

    7、闭包循环的问题

    OC中的循环问题

    定义block的时候,用setXXBlock能比较方便的打出格式

    • __weak和__unsafe_unretained的区别:前者释放后会置为nil而后者不会
    • __strong的使用:当一个Ablock里面嵌套另一个耗时操作的Bblock,在Bblock里需要使用self,为了防止使用时self已经被释放为空的情况,这时候会使用关键字__strong
      __weak typeof(self)weakSelf = self;
          [self setBlock:^(int a) {
              //
              __strong typeof(self)strongSelf = weakSelf;
              dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 *   NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                  //
                  [strongSelf xxx];
              });
          }];
      

    Swift中的使用

    class Person {
        
        var block: (()->())?
        
        func test() {
            block = {
                [weak self] in
                self
                print("test")
            }
        }
        
        deinit {
            print("Person释放了")
        }
        
    }
    
    var p: Person? = Person()
    p?.test()
    p = nil
    

    8、懒加载的使用

    使用关键字lazy

    class Dog {
        var age: Int = 0
    }
    
    class Person {
        //冒号后面一般跟具体的值、构造函数或者闭包
        lazy var name: Dog =  {
            //       () -> Dog in
            print("test")
            return Dog()   
        }()
    }
    

    注:与OC不同的是Swift中懒加载置为nil以后不能再重复加载了

    9、常见注释的写法

    另外,Swift里还可以开启注释(让FIXME像感叹号那样有提示便于查找),开启方法:把下面这段代码复制到BuildPhases→NewRunScriptPhases

    TAGS="TODO:|FIXME:"
    echo "searching ${SRCROOT} for ${TAGS}"
    find "${SRCROOT}" \( -name "*.swift" \) -print0 | xargs -0 egrep --with-filename --line-number --only-matching "($TAGS).*\$" | perl -p -e "s/($TAGS)/ warning: \$1/"
    
    

    10、访问权限问题

    OC
    默认是@protected

    OC中通常认为只有成员变量会存在访问权限问题,属性和方法都不存在;成员变量用箭头(->)访问;一旦修饰,该成员变量后面的都被修饰了,之道遇到下一个修饰

    Swift

    • internal:默认的,类似OC中的protected,当前模块内都可以访问
    • private:私有
    • fileprivate:在当前源文件中可以访问(当前源文件是指当前这一个xx.swift文件,当前模块是指当前这个Target,Swift中同一个模块不需要import)
      -public:修饰的对象可以跨模块,修饰类时不能继承,修饰方法时不能重写
    • open:修饰的对象可以跨模块,修饰类时可以继承,修饰方法时可以重写

    与OC不同的一个细节是,这些关键字都只会修饰接下来的一个对象,而不是后面所有的

    11、异常的抛出和处理

    格式与OC类似

    // 捕捉, 并且处理
    do {
        let content = try readFile(path: path)
    }catch {
        switch error {
        case FileError.NoPath:
            print("路径不存在")
        case FileError.UnAvailable:
            print("格式错误")
        case FileError.NoContent:
            print("没有内容")
        default:
            print("不知道")
        }
    }
    
    
    // try? 处理异常, 就代表, 告诉编译器, 我知道有可能会出现错误, 你帮我自动处理就好, 如果错误, 就直接给我nil < 如果没有错误, 就给我答案
    //let content = try? readFile(path: path)
    
    // try!, 代表, 我保证, 绝壁没有任何错误, 告诉编译器, 只负责给我值, 保证是有值得, 放心拿
    let content = try! readFile(path: path)
    

    12、Swift调用OC

    使用场景:可以调用OC写的三方框架

    在Swift项目中创建OC文件时会提示如下图



    注:这个桥接文件只对Swift引用OC有效

    13、OC调用Swift

    OC项目里调用Swift就没这么方便了,这时候同样会出现上图这个窗口,但是不要点Create,我们需要自己去创建(因为Swift文件没有单独的声明和实现文件,且是整个是一个模块)


    14、Playground的高级应用

    1. 资源共享
    2. 异步执行
    3. 多页面
    4. 动画时间轴

    相关文章

      网友评论

          本文标题:Swift3.0学习(三)

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