iOS9 Tutorials学习笔记(一)

1、repeat的用法

var i = 0
repeat{
print("i = \(i)")
i++
}while(i < 10)

和之前的 do while 是一样的

2、guard的用法

guard 的可以理解为对某项条件的判定,如果为false,则执行else代码块内容,否则就直接往下执行

//比较数字是否比10大
func greaterThan10(num:NSInteger){
    guard num > 10 else{
        print("小于10")
        return
    }
    print("符合条件")
}

greaterThan10(20)

3、Error Handling 的用法

在Swift2.0之后,方法可以使用throws来抛出异常。来处理方法执行中可能发生的异常。简单介绍一下异常的处理实现流程。
定义一个会抛出异常的方法,这里定义了一个protocol

//:定义一个protocol
protocol JSONParsable{
    static func parse(json:[String:AnyObject]) throws -> Self
}

定义抛出异常的类型

//:定义错误类型
enum ParseError:ErrorType{
   case MissingAttribute(message:String)
}

定义一个结构体来实现异常,抛出各种错误类型

//: 定义一个 struct来实现JSONParsable,并抛出错误
struct Person:JSONParsable {
    let firstName:String
    let lastName:String

    static func parse(json: [String : AnyObject]) throws -> Person {
        //哎,这里用到了guard ,注意
        guard let firstName = json["first_name"] as? String     else{
            let message = "Expected first_name String"
            throw ParseError.MissingAttribute(message: message)
        }
    
        guard let lastName = json["last_name"] as? String else{
            let message = "Expected last_name String"
        throw ParseError.MissingAttribute(message: message)
        }
        return Person(firstName: firstName, lastName: lastName)
    }    
}

异常状况的处理

//: 处理错误异常
do{
    let person = try Person.parse(["first_name":"first"])
}catch ParseError.MissingAttribute(let message){
    print(message)
}catch{
    print("Unexpected Error Type")
}

当然了,如果确定使用该方法是不会产生异常的,可以用!来直接获取,如果采取这种方式,所传数据格式不正确,则会直接编译错误。

//: 如果确定不会抛出异常,可以直接使用 try!
let person1 = try! Person.parse(["first_name":"first","last_name":"last"])

或者使用?来获取

//: 或者使用 try? 来确定是否可用
if let person2 = try? Person.parse(["first_name":"fir"]){
    print("可以解析出实例")
}
else{
    print("出问题了")
}

4、String Validator 主要学习返回多个错误的方法

总结一下上述知识点的使用方法,实现一个字符串的判定

先添加一个String类型的扩展

public extension String{
    public func startsWithCharacterFromSet(set:NSCharacterSet) -> Bool{
        guard !isEmpty else{
            return false
        }
        return rangeOfCharacterFromSet(set, options: [], range: startIndex ..< startIndex.successor()) != nil
    }

    public func endsWithCharacterFromSet(set:NSCharacterSet) -> Bool{
        guard !isEmpty else{
            return false
        }
        return rangeOfCharacterFromSet(set, options: [], range: endIndex.predecessor() ..< endIndex) != nil
    }  
}

定义一下错误类型

enum StringValidationError: ErrorType, CustomStringConvertible {

  case MustStartWith(set: NSCharacterSet, description: String)
  case MustContain(set: NSCharacterSet, description: String)
  case MustEndWith(set: NSCharacterSet, description: String)

  case CannotContain(set: NSCharacterSet, description: String)
  case CanOnlyContain(set: NSCharacterSet, description: String)
  case ContainAtLeast(set: NSCharacterSet, count: Int, description: String)

  case MinLengthNotReached(Int)
  case MaxLengthExceeded(Int)

  var description: String {
    let errorString: String
    switch self {
    case .MustStartWith(_, let description):
      errorString = "Must start with \(description)."
    case .MustEndWith(_, let description):
      errorString = "Must end with \(description)."
    case .MustContain(_, let description):
      errorString = "Must contain \(description)."
    case .CannotContain(_, let description):
      errorString = "Cannot contain \(description)."
    case .CanOnlyContain(set: _, let description):
      errorString = "Can only contain \(description)."
    case .ContainAtLeast(_, let count, let description):
      errorString = "Must contain at least \(count) \(description)."
    case .MinLengthNotReached(let minChars):
      errorString = "Must be at least \(minChars) characters."
    case .MaxLengthExceeded(let maxChars):
      errorString = "Must be shorter than \(maxChars) characters."
    }
    return errorString
  }
}

这里注意协议CustomStringConvertible的使用方式,实现description方法。
简单实现一下每次只返回一个错误的情况(上面有,不多说)

protocol StringValidationRule{
    func validate(string:String) throws -> Bool
    var errorType:StringValidationError{get}
}

//判定是否是字母开头的
struct StartsWithCharacterStringValidationRule:StringValidationRule {

    let characterSet:NSCharacterSet
    let description:String
    var errorType:StringValidationError{
        return .MustStartWith(set: characterSet, description: description)
    }

    func validate(string: String) throws -> Bool {
        if string.startsWithCharacterFromSet(characterSet){
            return true
        }else{
            throw errorType
        }
    }
}

let letterSet = NSCharacterSet.letterCharacterSet();

let startsWithRule = StartsWithCharacterStringValidationRule(characterSet: letterSet, description: "letter")
do {
    try startsWithRule.validate("foo")
    try startsWithRule.validate("12")
}catch let error{
    print(error)
}

接下来实现返回多个判定结果
实现协议

protocol StringValidator{
    var validationRules:[StringValidationRule] {get}
    func validate(string:String) -> (valid:Bool,errors:[StringValidationError])
}

使用extension来实现协议方法的一个默认实现

extension StringValidator{
    func validate(string:String) -> (valid:Bool,errors:[StringValidationError]){
        var errors = [StringValidationError]()
        for rule in validationRules{
            do{
                try rule.validate(string)
            }catch let error as StringValidationError{
                errors.append(error)
            }catch let error{
                fatalError("Unexpected error type:\(error)")
            }
        }
        return (valid:errors.isEmpty,errors:errors)
    }
}

使用结构体来实现该协议

struct StartsAndEndsWithStringValidator: StringValidator {
    let startsWithSet:NSCharacterSet
    let startsWithDescription:String
    let endsWithSet:NSCharacterSet
    let endsWithDescription:String

    var validationRules:[StringValidationRule]{
        return [
            StartsWithCharacterStringValidationRule(characterSet: startsWithSet, description: startsWithDescription),
            EndsWithCharacterStringValidationRule(characterSet: endsWithSet, description: endsWithDescription)
        ]
    }

    //这里没有实现方法validate也不会报错,是因为之前已经实现过默认,值得学习该方法
}

接下来就是实现了

let numberSet = NSCharacterSet.decimalDigitCharacterSet()
let startsAndEndWithValidator = StartsAndEndsWithStringValidator(startsWithSet: letterSet, startsWithDescription: "letter", endsWithSet: numberSet, endsWithDescription: "number")
startsAndEndWithValidator.validate("foo").errors.description

5、defer的使用

使用defer { ... }语法来确保在当前作用域内的代码无论在哪儿结束,在结束之前都会执行defer代码块里的代码

func testDefer(){
    print("执行defer之前的代码")

    defer{
        print("结束之前执行defer")
    }

    print("执行defer之后的代码")
}

testDefer()

打印顺序为:
执行defer之前的代码
执行defer之后的代码
结束之前执行defer

6、Pattern Matching (模式匹配)

在开始之前先记录一下map的一种用法,用来取出数组中同一类型的数据

struct Student {
    var name:String
    var id:String
}

var students:[Student] = []
//添加数据
for i in 0...10{
    let student = Student(name: "name\(i)", id: "id\(i)")
    students.append(student)
}

let names = students.map{$0.name}
//打印查看结果
for name in names{
    print(name)
}

第一种
for...in中使用where语句

let names = ["Charlie","Chris","Mic","John","Craig","Felipe"]
var namesThatStartWithC = [String]()
for cName in names where cName.hasPrefix("C") {
    namesThatStartWithC.append(cName)
}

结果:
["Charlie", "Chris", "Craig"]

第二种

//针对特定的case 输出
for case "name2" in names{
    print("name2")
}

第三种
if case 可以直接用来判断某个枚举对象属于哪一分支

 var slapLog = ""
 for author in authors {
   if case .Late(let daysLate) = author.status where daysLate > 2 {
     slapLog += "Ray slaps \(author.name) around a bit with a large trout \n"
   }
 }

6、OptionSetType

创建自己的OptionSet,就是声明一个实现了OptionSetType协议的结构体

struct RectangleBorderOptions: OptionSetType {
  let rawValue: Int

  init(rawValue: Int) { self.rawValue = rawValue }

  static let Top = RectangleBorderOptions(rawValue: 0)
  static let Right = RectangleBorderOptions(rawValue: 1)
  static let Bottom = RectangleBorderOptions(rawValue: 2)
  static let Left = RectangleBorderOptions(rawValue: 3)
  static let All: RectangleBorderOptions = [Top, Right, Bottom, Left]
}

7、判定系统

有些新的 APIs 不能在旧版本的系统上使用,所以使用时需要判定当前的系统版本

guard #available(iOS 9.0,*)else{
  print("The OS version below 9.0")
  return
}

比如我们使用 NSUserActivity这个类(最低支持8.0),并且app最低版本支持设置为7.0,此时将会出现错误

public var userActivity: NSUserActivity {
let activity = NSUserActivity(activityType: Employee.domainIdentifier)
activity.title = name
activity.userInfo = userActivityUserInfo
activity.keywords = [email, department]
activity.contentAttributeSet = attributeSet
return activity

}
解决方案一:

  public var userActivity: NSUserActivity {
    let activity = NSUserActivity(activityType:     Employee.domainIdentifier)
    activity.title = name
    activity.userInfo = userActivityUserInfo
    if #available(iOS 9.0, *) {
        activity.keywords = [email, department]
    } else {
        // Fallback on earlier versions
    }
    if #available(iOS 9.0, *) {
        activity.contentAttributeSet = attributeSet
    } else {
        // Fallback on earlier versions
    }
    return activity
  }

解决方案二:

@available(iOS 9.0, *)
  public var userActivity: NSUserActivity {
    let activity = NSUserActivity(activityType: Employee.domainIdentifier)
    activity.title = name
    activity.userInfo = userActivityUserInfo
    activity.keywords = [email, department]
    activity.contentAttributeSet = attributeSet
    return activity
  }

你可能感兴趣的:(iOS9 Tutorials学习笔记(一))