zoukankan      html  css  js  c++  java
  • JokeClient-Swift 仿写学习

    required init?(coder aDecoder: NSCoder) 可失败构造器

    在init关键字后面添加问号(init?)。
    可失败构造器会创建一个类型为自身类型的可选类型的对象。你通过return nil语句来表明可失败构造器在何种情况下应该“失败”。

    struct Animal {
        let species: String
        init?(species: String) {
            if species.isEmpty { return nil }
            self.species = species
        }
    }
    

    2、 as、as!、as?三种类型转换操作符使用详解

    as使用场合

    1、从派生类转换为基类,向上转型(upcasts)

        class Animal {}
        class Cat: Animal {}
        let cat = Cat()
        let animal = cat as Animal
    

    2.消除二义性,数值类型转换

    let num1 = 42 as CGFloat
    let num2 = 42 as Int
    let num3 = 42.5 as Int
    let num4 = (42 / 2) as Double
    

    3. switch 语句中进行模式匹配

    如果不知道一个对象是什么类型,你可以通过switch语法检测它的类型,并且尝试在不同的情况下使用对应的类型进行相应的处理

    switch animal {
    case let cat as Cat:
        print("如果是Cat类型对象,则做相应处理")
    case let dog as Dog:
        print("如果是Dog类型对象,则做相应处理")
    default: break
    }
    

    as!使用场合

    as? 和 as! 操作符的转换规则完全一样。但 as? 如果转换不成功的时候便会返回一个 nil 对象。成功的话返回可选类型值(optional),需要我们拆包使用。
    由于 as? 在转换失败的时候也不会出现错误,所以对于如果能确保100%会成功的转换则可使用 as!,否则使用 as?

    
    let animal:Animal = Cat()
     
    if let cat = animal as? Cat{
        print("cat is not nil")
    } else {
        print("cat is nil")
    }
    

    转自:Swift - as、as!、as?三种类型转换操作符使用详解(附样例)

    方法的局部参数名称和外部参数名称

    函数参数可以同时有一个局部名称(在函数体内部使用)和一个外部名称(在调用函数时使用),详情参见函数的外部参数名。方法参数也一样(因为方法就是函数,只是这个函数与某个类型相关联了)。但是,方法和函数的局部名称和外部名称的默认行为是不一样的。

    STATIC 和 CLASS

    Swift 中表示 “类型范围作用域” 这一概念有两个不同的关键字,它们分别是 static 和 class。

    有一个比较特殊的是 protocol。在 Swift 中 class,struct 和 enum 都是可以实现某个 protocol 的。那么如果我们想在 protocol 里定义一个类型域上的方法或者计算属性的话,应该用哪个关键字呢?答案是使用 static 进行定义。在使用的时候,struct 或 enum 中仍然使用 static,而在 class 里我们既可以使用 class 关键字,也可以用 static,它们的结果是相同的

    现在只需要记住结论,在任何时候使用 static 应该都是没有问题的。

    摘自:STATIC 和 CLASS

    ANY 和 ANYOBJECT

    Any 和 AnyObject 是 Swift 中两个妥协的产物,也是很让人迷惑的概念。

    AnyObject 可以代表任何 class 类型的实例
    Any 可以表示任意类型,甚至包括方法 (func) 类型

    Swift 最主要的用途依然是使用 Cocoa 框架进行 app 开发,因此为了与 Cocoa 架构协作,将原来 id 的概念使用了一个类似的,可以代表任意 class 类型的 AnyObject 来进行替代。

    在 Swift 中编译器不仅不会对 AnyObject 实例的方法调用做出检查,甚至对于 AnyObject 的所有方法调用都会返回 Optional 的结果。

    Swift 中所有的基本类型,包括 Array 和 Dictionary 这些传统意义上会是 class 的东西,统统都是 struct 类型,并不能由 AnyObject 来表示,于是 Apple 提出了一个更为特殊的 Any,除了 class 以外,它还可以表示包括 struct 和 enum 在内的所有类型。

    摘自:ANY 和 ANYOBJECT

    SELECTOR

    在 Swift 中没有 @selector 了,取而代之,从 Swift 2.2 开始我们使用 #selector 来从暴露给 Objective-C 的代码中获取一个 selector。

    
    func callMe() {
        //...
    }
    
    func callMeWithParam(obj: AnyObject!) {
        //...
    }
    func turnByAngle(theAngle: Int, speed: Float) {
        //...
    }
    
    let someMethod = #selector(callMe)
    let anotherMethod = #selector(callMeWithParam(_:))
    let method = #selector(turnByAngle(_:speed:))
    
    

    最后需要注意的是,selector 其实是 Objective-C runtime 的概念,如果你的 selector 对应的方法只在 Swift 中可见的话 (也就是说它是一个 Swift 中的 private 方法),在调用这个 selector 时你会遇到一个 unrecognized selector 错误:

    //错误:
    private func callMe() {
         //...
    }
    
    NSTimer.scheduledTimerWithTimeInterval(1, target: self,
                selector:#selector(callMe), userInfo: nil, repeats: true)
     
    //正确          
    @objc private func callMe() {
        //...
    }
    
    NSTimer.scheduledTimerWithTimeInterval(1, target: self,
                 selector:#selector(callMe), userInfo: nil, repeats: true)
                
    

    最后,值得一提的是,如果方法名字在方法所在域内是唯一的话,我们可以简单地只是用方法的名字来作为 #selector 的内容。相比于前面带有冒号的完整的形式来说,这么写起来会方便一些:

    
    let someMethod = #selector(callMe)
    let anotherMethod = #selector(callMeWithParam)
    let method = #selector(turnByAngle)
    
    

    但是,如果在同一个作用域中存在同样名字的两个方法,即使它们的函数签名不相同,Swift 编译器也不允许编译通过:

    
    func commonFunc() {
    
    }
    
    func commonFunc(input: Int) -> Int {
        return input
    }
    
    let method = #selector(commonFunc)
    // 编译错误,`commonFunc` 有歧义
    
    
    

    对于这种问题,我们可以通过将方法进行强制转换来使用:

    
    let method1 = #selector(commonFunc as ()->())
    let method2 = #selector(commonFunc as Int->Int)
    
    

    转自:SELECTOR

    guard

    swift 2.0 带来了 guard 语句,这里主要用来与 if 来做比较

    
    //好的写法
    func createPerson() throws -> Person {
            guard let age = age, let name = name
                where name.characters.count > 0 && age.characters.count > 0 else {
                    throw InputError.InputMissing
            }
    
            guard let ageFormatted = Int(age) else {
                throw InputError.AgeIncorrect
            }
    
            return Person(name: name, age: ageFormatted)
        }
        
    //差的写法
    func createPersonNoGuard() -> Person? {
        if let age = age, let name = name
            where name.characters.count > 0 && age.characters.count > 0
        {
            if let ageFormatted = Int(age) {
                return Person(name: name, age: ageFormatted)
            } else {
                return nil
            }
        } else {
            return nil
        }
    }    
    
    

    使用 guard 可以很容易地看到 Person 实例的返回值,这样就能明白这个方法的主要目的是什么

    转自:为什么 guard 比 if 好

  • 相关阅读:
    P1726 上白泽慧音
    P1993 小k的农场
    P1983 车站分级
    P1525 关押罪犯【二分+二分图】
    P1268 树的重量【构造】
    P1113 杂务
    F.Three pahs on a tree
    P1522 牛的旅行
    两个约束下的dp问题
    dp 最大正方形
  • 原文地址:https://www.cnblogs.com/coolwxb/p/JokeClientSwift-fang-xie-xue-xi.html
Copyright © 2011-2022 走看看