swift_swiftyjson - CSDN
swift 订阅
Swift,苹果于2014年WWDC苹果开发者大会发布的新开发语言,可与Objective-C共同运行于macOS和iOS平台,用于搭建基于苹果平台的应用程序。Swift是一款易学易用的编程语言,而且它还是第一套具有与脚本语言同样的表现力和趣味性的系统编程语言。Swift的设计以安全为出发点,以避免各种常见的编程错误类别。 [1]  2015年12月4日,苹果公司宣布其Swift编程语言开放源代码。长600多页的The Swift Programming Language [2]  可以在线免费下载。 展开全文
Swift,苹果于2014年WWDC苹果开发者大会发布的新开发语言,可与Objective-C共同运行于macOS和iOS平台,用于搭建基于苹果平台的应用程序。Swift是一款易学易用的编程语言,而且它还是第一套具有与脚本语言同样的表现力和趣味性的系统编程语言。Swift的设计以安全为出发点,以避免各种常见的编程错误类别。 [1]  2015年12月4日,苹果公司宣布其Swift编程语言开放源代码。长600多页的The Swift Programming Language [2]  可以在线免费下载。
信息
源    于
Objective-C
外文名
Swift
发布时间
2014年6月2日
发行组织
Apple
中文名
雨燕
参考语言
C,JavaScript,Python,Java
系    统
macOS,iOS,linux
SWIFT发展历史
2014-6-3 Swift于WWDC苹果开发者大会发布。 发布(6张) 2014-6-4 《Swift中文版》翻译组在github上进行协同翻译 [3]  。此项目开始不到一周就获得了1067个star。该项目的发起人是北航的大三学生 [4]  。2014-6-12《Swift中文版》第一版发布 [5]  。2015年12月4日,苹果公司宣布其Swift编程语言开放源代码 [3]  。长600多页的The Swift Programming Language [2]  可以在线免费下载。同时可以在苹果官方Github下载 [3]  。2020年最新一期的编程语言排行榜显示,Swift从第15名上升至第9名。 [6] 
收起全文
精华内容
参与话题
  • Swift5语言入门实例教程

    千人学习 2019-12-05 11:06:29
    包含常量与变量、基本数据类型,以及Swift语言中的新数据类型—元组型和可选型的内容。同时还讲解了运算符和表达式、流程控制语句、字符和字符串、集合类型、函数和闭包。此外,Swift面向对象的枚举、结构体、类,...
  • Swift编程语言(Swift 5)

    2020-07-29 14:19:59
    介绍: 《Swift 编程语言》是苹果官方对 Swift 语言做的权威指南,很遗憾苹果公司并没有进行多语言支持。所以我独立发起了这个手册的翻译工作——与其他现存翻译不同的是:它同步更新苹果官方的 Swift 开发者预览版 ...
  • Swift快速入门

    2020-09-08 06:36:46
    Swift中规定:在定义一个标识符时必须明确说明该标识符是一个常量还是变量 1、使用 let 定义常量,定义之后不可以修改 let number = 10 // 常量不可以修改 number = 20 ❌ 2、使用 var 定义变量,定义之后可以...

    一、常量&变量

    在Swift中规定:在定义一个标识符时必须明确说明该标识符是一个常量还是变量

    1、使用 let 定义常量,定义之后不可以修改

    let number = 10
    // 常量不可以修改
    number = 20 ❌

    2、使用 var 定义变量,定义之后可以修改

    var number = 10
    
    number = 20 

    ⚠️编译器会根据给变量或常量所赋的值,推断它的数据类型。所以这里系统会认为number是Int类型的

    ⚠️ swift中输出语句:print函数

    print("Hello Swift")

    二、数据类型

    Swift中的数据类型也有:整型/浮点型/字符串/对象类型/结构体类型等等

    ⚠️ Swift是强类型语言

    // 定义变量时没有指定明确的类型,但是因为赋值给i一个20.20为整型.因此i为整型
    var i = 20
    // 如果之后赋值给i一个浮点型数值,则会报错
    // i = 30.5 ❌

    如果定义一个标识符时有直接进行赋值,那么标识符后面的类型可以省略

    如果想要指定常量或变量的数据类型

    var number:Float = 10
    var name:String = "花花"

    Swift中的基本运算

    ⚠️ Swift中在进行基本运算时必须保证类型一致,否则会出错

    ⚠️ 值不会隐式转换,需要显示转换成其他数据类型

    let a = 10
    let b = 3.14
    
    // 错误写法
    // let c = a + b ❌
    // let c = a * b ❌
    
    // 正确写法
    let c = Double(a) + b
    let d = a + Int(b)

    三、字符串

    字符串的使用

    1、遍历字符串

    // 字符串遍历
    var str = "Hello, Swift"
    for c in str {
        print(c)
    }

    2、字符串拼接

    let str1 = "Hello"
    let str2 = "Swift"
    let str3 = str1 + str2

    3、字符串插值

    let age = 18
    let result = "My name is Huahua, age is \(age)"

    4、字符串的格式化

    let str = String(format: "%@=%@", key, value)

    5、使用2对3引号可以表示多行字符串

    let string = """
    Hello Swift!
    Hello Swift!
    Hello Swift!
    """

    ⚠️引号所在行,引号后不能有其他元素

    四、数组

    数组是一串有序的由相同类型元素构成的集合,数组中的集合元素是有序的,可以重复出现

    ⚠️ 声明数组

    // let代表不可变数组
    let array:Array<String>
    
    // var代表可变数组
    var array: [String]

    ⚠️ 初始化数组

    // 定义一个可变数组,必须初始化才能使用
    var array1 : [String] = [String]()
    
    // 定义一个不可变数组
    let array2 : [Any] = ["花花", 18]
    
    // 定义时直接初始化
    var array = ["a", "b", "c"]
    
    // 先定义,后初始化
    var array : Array<String>
    array = ["a", "b", "c"]

    2、对数组的基本操作

    // 添加数据
    array.append("abc")
    
    // 删除元素
    array.removeFirst()
    
    // 修改元素
    array[0] = "asd"
    
    // 取值
    array[1]
    
    // 数组合并
    // 注意:只有相同类型的数组才能合并
    var array1 = ["a", "b","c"]
    var array2 = ["d", "e"]
    var array3 = array1 + array2

    3、数组的遍历

    // 遍历数组
    for i in 0..<array.count {
        print(array[i])
    }
    
    // forin方式
    for item in array {
        print(item)
    }
    
    // 设置遍历的区间
    for item in array[0..<2] {
        print(item)
    }

    五、字典

    字典是由两部分集合构成的,一个是键(key)集合,一个是值(value)集合。键集合是不能有重复元素的,值集合可以重复,键和值是成对出现的。

    1、字典的初始化

    // 定义一个可变字典
    var dict1 : [String : Any] = [String : Any]()
    
    // 定义一个不可变字典
    let dict2 = ["name" : "花花", "age" : 18]

    ⚠️ 声明字典

    var dict1: Dictionary<Int, String>
    var dict2: [Int: String]

    2、字典的基本操作

    // 添加数据
    dict["height"] = 1.88
    
    // 删除字段
    dict.removeValueForKey("height")
    
    // 修改字典
    dict["name"] = "花花"
    
    // 查询字典
    dict["name"]
    
    // 字典的合并
    var dict1 = ["name" : "花花", "age" : 18]
    var dict2 = ["height" : 1.8]
    
    // 字典不可以直接相加合并
    for (key, value) in dict2 {
        dict1[key] = value
    }

    3、字典的遍历

    // 遍历字典中所有的值
    for value in dict.values {
        print(value)
    }
    
    // 遍历字典中所有的键
    for key in dict.keys {
        print(key)
    }
    
    // 遍历所有的键值对
    for (key, value) in dict {
        print(key)
        print(value)
    }

    六、元祖

    元祖是一种数据结构,类似于数组或字典,用于定义一组数据

    1、定义元祖

    ("1001", "花花", 18, 90)
    (id:"1001", name:"张三", age:18, score:90)

    2、元祖的简单使用

    // 元祖:HTTP错误
    // 写法一:
    let error = (404, "Not Found")
    print(error.0)
    print(error.1)
    
    // 写法二:
    let error = (errorCode : 404, errorInfo : "Not Found")
    print(error.errorCode)
    print(error.errorInfo)
    
    // 写法三:
    let (errorCode, errorIno) = (404, "Not Found")
    print(errorCode)
    print(errorIno)

    七、可选类型(Optional)

    在swift开发中,nil也是一个特殊的类型。

    1、可选类型的定义

    // 写法一:定义可选类型
    let string : Optional<String> = nil
    
    // 写法二:定义可选类型,语法糖(常用)
    let string : String? = nil
    
    // 错误写法
    // let string : String = nil ❌

    2、可选类型的使用

    // 定义可选类型
    var string : String? = nil
    
    // 给可选类型赋值
    string = "Hello world"
    
    // 打印结果
    print(string)
    
    // 结果:Optional("Hello world")
    // 因为打印出来的是可选类型,所有会带Optional

    3、解包

    解包就是取出可选类型的真实值

    print(string!) // 结果:Hello world
    
    ⚠️注意:如果可选类型为nil,强制取出其中的值(解包),程序会崩溃
    
    string = nil
    print(string!) // 报错 
    
    // 正确写法:
    if string != nil {
        print(string!)
    }
    
    // 简单写法:为了让在if语句中可以方便使用string
    if var str = string {
        print(str)
    }

    4、可选类型使用实例

    // 通过该方法创建的URL,可能有值,也可能没有值
    
    // 正确写法:使用可选类型来接收
    let url : URL? = URL(string: "http://www.baidu.com")
    
    // 错误写法:如果返回值是nil时,就不能接收了
    let url : URL = URL(string: "http://www.baidu.com")
    
    // 通过url来创建request对象
    if let tempUrl = url {
        let request = NSURLRequest(URL: tempUrl)
    }

    八、函数

    函数格式:

    func 函数名(参数列表) -> 返回值类型 {
        代码块
        return 返回值
    }
    • func是关键字,多个参数列表之间可以用逗号(,)分隔,也可以没有参数
    • 使用箭头“->”指向返回值类型
    • 如果函数没有返回值,返回值为Void.“-> 返回值类型”部分可以省略

    1、常见函数类型

    <1 没有参数,没有返回值

    func test() -> Void {
        print("Hello Swift")
    }
    
    // 调用函数
    test()
    
    // 简单写法
    // 如果没有返回值,后面的内容可以都不写
    func test2() {
       print("Hello Swift")
    }

    <2 有参数,没返回值

    func test(name : String) {
        print("Hello\(name)")
    }
    test(name: "Swift")

    <3 没参数,有返回值

    func getSth() -> String {
        return "花花"
    }
    var str = getSth()
    print(str)

    <4 有参数,有返回值

    func sum(num1 : Int, num2 : Int) -> Int {
        return num1 + num2
    }
    var result = sum(num1: 20, num2: 30)
    print(result)

    2、外部参数&内部参数

    在函数外面可以看到的参数,就是外部参数。在函数内部可以看到的参数,就是内部参数。

    ⚠️ 如果不想要外部参数,可以在参数名称前加_

    // number1、number2和number3是外部参数的名称
    
    func mutiple(number1 num1 : Int, number2 num2 : Int, number3 num3 : Int) -> Int {
        return num1 * num2 * num3
    }
    var result1 = mutiple(number1: 20, number2: 4, number3: 5)

    3、默认参数

    某些情况,如果没有传入具体的参数,可以使用默认参数

    func makecoffee(type :String = "卡布奇诺") -> String {
        return "制作一杯\(type)咖啡。"
    }
    
    let coffee1 = makecoffee("拿铁")
    let coffee2 = makecoffee()

    4、可变参数

    swift中函数的参数个数可以变化,它可以接受不确定数量的输入类型参数(必须具有相同的类型),我们可以通过在参数类型名后面加入(...)的方式来指示这是可变参数

    func sum(numbers:Double...) -> Double {
        var total: Double = 0
        for number in numbers {
            total += number
        }
        return total
    }
    
    sum(100.0, 20, 50)

    5、引用类型

    默认情况下,函数的参数是值传递.如果想改变外面的变量,则需要传递变量的地址

    inout关键字

    func swap(a : inout Int, b : inout Int) {
       let temp = a
       a = b
       b = temp
    }
    
    var a = 10
    var b = 20
    swap(a: &a, b: &b)
    print("a:\(a), b:\(b)")

    6、方法重载

    方法重载:方法名称相同,但是参数不同

    func mutiple(_ num1: Int, _ num2 :Int) -> Int {
        return num1 * num2
    }
    
    var result2 = mutiple(20, 20)

    九、 闭包

    闭包是一个特殊函数

    1、定义闭包

    类型:(形参列表)->(返回值)

    技巧:定义闭包类型时,直接写()->().再填充参数和返回值

    {
        (形参) -> 返回值类型 in
        // 执行代码
    }

    2、闭包的使用

    // 定义网络请求类
    class HttpTool: NSObject {
        func loadRequest(callBack: ()->()){
            print("加载数据..")
            callBack()
        }
    }
    
    // 网络请求
    let httpTool = HttpTool()
    httpTool.loadRequest ({ () -> () in
        print("加载完成")
    })   

    3、闭包的简写

    • 如果闭包没有参数,没有返回值.in和in之前的内容可以省略
    httpTool.loadRequest({
        print("加载完成")
    })

    ⚠️ 尾随闭包

    • 尾随闭包写法
      • 如果闭包是函数的最后一个参数,则可以将闭包写在()后面
      • 如果函数只有一个参数,并且这个参数是闭包,那么()可以不写
    httpTool.loadRequest() {
        print("加载完成")
    }
    // 开发中建议该写法
    httpTool.loadRequest {
        print("加载完成")
    }

    4、闭包的循环使用

    • 如果在HttpTool中有对闭包进行强引用,则会形成循环引用
    class HttpTool: NSObject {
        // 定义属性,强引用传入的闭包
        var callBack : (()->())?
    
        func loadRequest(callBack : ()->()){
            callBack()
            self.callBack = callBack
        }
    }
    • swift中解决循环引用的方式
    // [weak self] () -> () in
    httpTool.loadRequest { [weak self] in
        self.view.backgroundColor = UIColor.redColor()
    }

    十、 懒加载

    定义:用到时候才加载

    懒加载的本质是,在第一次使用的时候执行闭包,将闭包的返回值赋值给属性

    • lazy的作用是只会赋值一次
    lazy var array : [String] = {
        () -> [String] in
        return ["a", "b", "c"]
    }()

    十一、类

    Swift是一门面向对象开发的语言,面向对象的基础是类

    1、类的定义

    class 类名 : SuperClass {
        // 定义属性和方法
    }

    ⚠️ 定义的类,可以没有父类.那么该类是 rootClass

    2、类的属性

    • Swift中类的属性有多种
      • 存储属性:存储实例的常量和变量
      • 计算属性:通过某种方式计算出来的属性
      • 类属性:与整个类自身相关的属性

    存储属性

    • 存储属性是最简单的属性,它作为类实例的一部分,用于存储常量和变量
    • 可以给存储属性提供一个默认值,也可以在初始化方法中对其进行初始化
    class Student : NSObject {
        // 存储属性
        var age : Int = 0
        var name : String?
        var englishScore : Double = 0.0
        var mathScore : Double = 0.0
    }
    
    // 创建学生对象
    let stu = Student()
    // 给存储属性赋值
    stu.age = 10
    stu.name = "花花"
    stu.englishScore = 80.0
    stu.mathScore = 90.0

    计算属性

    • 计算属性并不存储实际的值,而是提供一个getter和一个可选的setter来间接获取和设置其它属性
    • 存储属性一般只提供getter方法
    • 如果只提供getter,而不提供setter,则该计算属性为只读属性,并且可以省略get{}
    class Student : NSObject {
        // 存储属性
        var age : Int = 0
        var name : String?
        var englishScore : Double = 0.0
        var mathScore : Double = 0.0
        
        // 计算属性
        var averageScore : Double {
            get {
                return (englishScore + mathScore) / 2
            }
            // newValue是系统分配的变量名,内部存储着新值
            set {
                self.averageScore = newValue
            }
        }
    }

    类属性

    • 类属性是与类相关联的,而不是与类的实例相关联
    • 类属性使用static来修饰
    class Student : NSObject {
        // 存储属性
        var age : Int = 0
        var name : String?
    
        var englishScore : Double = 0.0
        var mathScore : Double = 0.0
    
        // 计算属性
        var averageScore : Double {
            get {
                return (englishScore + mathScore) / 2
            }
    
            // 没有意义.newValue是系统分配的变量名,内部存储着新值
            set {
                self.averageScore = newValue
            }
        }
    
        // 类属性
        static var corseCount : Int = 0
    }
    
    // 设置类属性的值
    Student.corseCount = 3

    3、监听属性的改变

    Swift中可以通过属性观察者来监听和响应属性值的变化

    • 通常是监听存储属性和类属性的改变.(对于计算属性,我们不需要定义属性观察者,因为我们可以在计算属性的setter中直接观察并响应这种值的变化)

    • 我们通过设置以下观察方法来定义观察者

      • willSet:在属性值被存储之前设置。此时新属性值作为一个常量参数被传入。该参数名默认为newValue,我们可以自己定义该参数名
      • didSet:在新属性值被存储后立即调用。与willSet相同,此时传入的是属性的旧值,默认参数名为oldValue
    class Person : NSObject {
        var name : String? {
            // 可以给newValue自定义名称
            willSet (){ 
                // 属性即将改变,还未改变时会调用的方法
                // 在该方法中有一个默认的系统属性newValue,用于存储新值
                print(newValue)
            }
            didSet (oldValue) {
                // 属性值已经改变了,会调用的方法
                // 在该方法中有一个默认的系统属性oldValue,用于存储旧值
                print(oldValue)
            }
        }
        var age : Int = 0
        var height : Double = 0.0
    }
    
    let p : Person = Person()
    
    // 在赋值时,监听该属性的改变
    // 在OC中是通过重写set方法
    // 在swift中,可以给属性添加监听器
    p.name = "花花"

    十二、类的构造函数

    • 创建一个类时,必然会调用一个构造函数
    • 即便是没有编写任何构造函数,编译器也会提供一个默认的构造函数。
    • 如果是继承自NSObject,可以对父类的构造函数进行重写

    1、构造函数的基本使用

    class Person: NSObject {
        var name : String = ""
        var age : Int = 0
    
        // 重写了NSObject(父类)的构造方法
        override init() {
            name = ""
            age = 0
        }
    }
    
    // 创建一个Person对象
    let p = Person()

    2、初始化时给属性赋值

    很多时候,我们在创建一个对象时就会给属性赋值,可以自定义构造函数 ⚠️ 如果自定义了构造函数,会覆盖init()方法.即不在有默认的构造函数

    class Person: NSObject {
        var name : String?
        var age : Int = 0
    
        // 自定义构造函数,会覆盖init()函数
        init(name : String, age : Int) {
            self.name = name
            self.age = age
        }
    }
    
    // 创建一个Person对象
    let p = Person(name: "花花", age: 18)

    十三、Swift逻辑分支

    通过分支语句可以控制程序的执行流程

    • 在Swift的判断句中必须有明确的真假 false/true

    1、if语句

    let a = 10
    
    // 错误写法:❌
    //if a {
    //    print("a")
    //}
    
    // 正确写法
    if a > 9 {
        print(a)
    }

    这个是可选类型,因为只有声明成可选类型后,才可以判断是否为空

    let view : UIView? = UIView()
    
    // 判断如果view有值,则设置背景颜色
    // 错误写法 ❌
    //if view {
    //    view.backgroundColor = UIColor.redColor()
    //}
    
    if view != nil {
        view!.backgroundColor = UIColor.redColor()
    }

    2、if/else if/else 语句

    let score = 87
    
    if score < 60 {
        print("不及格")
    } else if score <= 70 {
        print("及格")
    } else if score <= 80 {
        print("良好")
    } else if score <= 90 {
        print("优秀")
    } else {
        print("完美")
    }

    3、三目运算符

    var a = 10
    var b = 50
    
    var result = a > b ? a : b
    print(result)

    4、guard语句

    guard是Swift2.0新增的语法,它设计的目的是提高程序的可读性

    • guard语法:
      • 当条件表达式为true时候跳过else语句中的内容,执行后面的代码
      • 条件表达式为false时候执行else语句中的内容,跳转语句一般是return、break、continue和throw
    guard 条件表达式 else {
        // do sth..
        return
    }
    do sth...

    使用实例:

    var age = 18
    
    func online(age : Int) -> Void {
        guard age >= 18 else {
            print("回家去")
            return
        }
    
        print("可以上网")
    }
    
    online(age)

    5、switch分支

    switch后可以不跟(),case后可以不跟break(默认会有break)

    let sex = 0
    
    switch sex {
    case 0 :
        print("男")
    case 1 :
        print("女")
    default :
        print("其他")
    }

    如果希望出现之前的case穿透,则可以使用关键字fallthrough

    let sex = 0
    
    switch sex {
    case 0:
        fallthrough
    case 1:
        print("正常人")
    default:
        print("其他")
    }

    swift支持多种数据类型

    • 浮点型的switch判断
    let f = 3.14
    switch f {
    case 3.14:
        print("π")
    default:
        print("not π")
    }
    • 字符串类型
    let opration = "+"
    
    switch opration {
        case "+":
            print("+")
        case "-":
            print("-")
        case "*":
            print("*")
        case "/":
            print("/")
    default:
        break
    }
    • switch支持区间判断
    let score = 88
    
    switch score {
    case 0..<60:
        print("不及格")
    case 60..<80:
        print("及格")
    case 80..<90:
        print("良好")
    case 90..<100:
        print("优秀")
    default:
        print("满分")
    }

    十四、循环

    1、for循环

    for i in 0..<10 {
        print(i)
    }
    
    for i in 0...10 {
        print(i)
    }

    2、while循环

    var a = 0
    while a < 10 {
        a++
    }

    3、repeat while 循环

    let b = 0
    repeat {
        print(b)
        b++
    } while b < 20

     

     

    展开全文
  • 最近,除了N多的基于Swift的服务端开发框架,笔者不由深思,到底该这么评价Swift呢?不可否认,在iOS的开发领域,Swift是比OJC拥有着优势,那么在通用语言这个层次上比较时,它又如何呢?Apple 在推出 Swift 时就将...

    一  从语法角度,他的优势点

    最近,除了N多的基于Swift的服务端开发框架,笔者不由深思,到底该这么评价Swift呢?不可否认,在iOS的开发领域,Swift是比OJC拥有着优势,那么在通用语言这个层次上比较时,它又如何呢?Apple 在推出 Swift 时就将其冠以先进,安全和高效的新一代编程语言之名。前两点在 Swift 的语法和语言特性中已经表现得淋漓尽致:像是尾随闭包,枚举关联值,可选值和强制的类型安全等都是 Swift 显而易见的优点。

    1. Comparison

      oc java c# c++

    swift

    python
    值对象 没有 没有
    指针(缺陷) 没有 没有 没有 没有
    内存管理 引用计数 垃圾回收 垃圾回收 智能指针(缺陷) 引用计数 垃圾回收
    多返回值 没有 没有 没有 没有
    脚本语言特性 没有 没有 没有 没有
    移动端支持 ios android 游戏 游戏 ios 较少(缺陷)
                 

    近来Swift与Rust都挺好的,一个背靠Apple,一个是Mozilla的亲儿子。不可否认这二者都是工程领域的集大成者,不过笔者认为Swift是会比D或者Rust具有更大的可用性与吸引力,当然,他们的瞄准的目标点也不一样。D与Rust适合于那些长期使用C++并且已经适应了要去掌握N多的语法与概念的,但是想要使用些更加清晰明了与安全的语言。这类型的开发者往往从事着类似于游戏引擎、编译器、加解密库、HTML渲染引擎等等类似的工作。

    Swift呢,更多意义上是一门面向于应用编程的语言,它很容易上手,在某些方面它应该与Go、Java、Python以及C#相提并论。不过Swift比这些会更容易开始学习,它的helloworld只需要一行代码就好了,并且它是支持函数的(不像Java那样完全的OO)。你不需要学习任何的类与对象的知识就可以开始撰写简易的Swift的代码。基于此,Swift是更合适用作一种教学语言的,它还有像脚本语言一样的交互环境,也就是REPL以及Xcode本身提供的PlayGround。

    综上所述,Swift拥有着被广泛使用以及当做第一学习语言的潜质。并且,Swift并不是像PHP那样的语法特性较少的语言,它拥有足够的深度来满足Rust或者D这样的用户的需求。与Go相比的话,Go背靠Google,也是个非常容易上手的语言,并且号称自带并发。Swift在语法层次上会更加高级,并且Swift并没有使用GC机制,因此可以与C更好地相兼容。也就是说,你可以用Swift编写任何的库来供任何语言使用,只要这些语言可以使用C的库。这些特质保证了Swift拥有着比Java、C#、Python、Ruby以及Go更广阔的适用范围。后面这几个家伙,因为有GC的存在,不适合为其他语言提供基本库。我也很喜欢Go,但是毫无疑问,Swift会是个更加严谨与安全的语言。类型检测系统会帮助处理很多的错误,Go目前是很合适于Web开发但是不适合科学计算与游戏引擎这些你必须要大量自定义操作符来处理向量啊、矩阵运算这样的。

    因此,Swift可以被定义为一个安全并且用户友好的语言,并且可以像脚本语言那样方便实验与使用,其实swift想做移动端的python

     

    1.1  TypeAlias 类型别名:类似 C++ 的 typedef 和 Golang 的 type

    Swift 版本:

    typealias status = Int8

    C++ 版本:

    typedef status int

    Golang 版本:

    type status int

    1.2   Optional 可选类型: 类似 Haskell 中的 Maybe 类型

    Optional 可选类型,表示变量有值时返回存储的值,没有值返回 nil 。它可以在变量未声明的情况下确保后面调用的安全性。

    用法为 Optional<Type> 或者 Type? 。 例如:

    var i:Optional<Int>
    var str:String?

    Haskell 中也有类似的东西: Maybe 类型,它是这样定义的:

    data Maybe a =  Nothing | Just a deriving (Eq, Ord, Read, Show)

    用法也类似:

    i :: Maybe Int

    1.3  枚举支持元组:类似 Rust

    Swift 不仅支持基本的枚举类型,还可以是元组:

    enum Product
    {
        case Car(String, Int)
        case Phone(String, String)
    }

    Rust 中的枚举也有类似用法:

    enum Shape {
    	Circle { center: Point, radius: f64 },
    	Retangle { top_left: Point, bottom_right: Point }
    }

    1.4  用于 switch case 的 fallthrough: 类似 Golang 中的 fallthrough

    当初学 C 语言的时候就觉得 switch case 设计成默认贯穿很坑爹:实际开发中多数是不需要贯穿的,这就导致代码中一大堆 break 

    现在 Swift 终于从 Golang 吸收过来这个特性,一般不需要处理 case ,少数需要贯穿的情况才加上 fallthrough ,二者用法也类似,代码就不贴了。

    1.5  switch case 支持 where 语句:类似 Haskell 中 Pattern Guard 的 where 语句

    Swift 中的 switch case 语句支持 where 条件判断:

    let point = (-1, 2, 0)
    switch point
    {
    case (let x, _, _):
        println("x: \(x)")
        fallthrough
    case (x, y, z) where x * y * z == 0:
        println("x: \(x), y: \(y), z: \(z)")
    default:
        println()
    }

    Haskell 中虽然没有 switch case ,但有类似的 Pattern Guard,而且也支持 where 语句:

    funcBMI :: (RealFloat a) => a -> a -> String
    funcBMI weight height
    	| bmi <= bmi_thin = "Thin."
    	| bmi >= bmi_fat = "Fat."
    	| otherwise = "Normal."
    	where bmi = weight/height^2
    	      (bmi_thin,bmi_fat) = (18.5,30.0)

    1.6  支持函数类型:类似 C++11 中的 std::function 类型

    Swift 中可定义函数类型,并作为变量类型、参数类型、返回值类型:

    //定义函数类型:
    typealias FuncType = (Double, Double) -> Double
    
    //函数类型的变量:
    var funcDDD : FuncType
    
    //函数类型的参数:
    func printFuncResult(fun : FuncType, x : Double, y : Double) {
        println(fun(x, y))
    }
    
    //函数类型的返回值:
    func getFunc() -> FuncType {
        return funcDDD
    }

    甚至还可以将函数类型结合闭包使用:

    typealias FuncType = (Double, Double) -> Double
    
    func printFuncResult(x : Double, y : Double, fun : FuncType) {
        println("\(fun(x, y))")
    }
    
    //定义闭包:
    let funPlus = { (x : Double, y : Double) -> Double in return x + y }
    
    //将闭包作为函数类型的参数传入函数:
    printFuncResult(0.1234, 5.6789, funPlus)

    C++11 中的 std::function 也可定义一个函数指针,也有上述类似用法:

    //定义函数类型指针变量:
    std::function<double(double, double)> multiply;
    
    //将变量声明为该类型的 Lambda:
    multiply = [] (double x, double y) -> double {
    	return x * y;
    };
    
    //调用 Lambda:
    std::cout << multiply(1.234, 5.6789) << std::endl;

    1.7  支持运算符重载和定义新运算符:类似 C++ 中的运算符重载

    Swift 中可用 prefix 重载前缀运算符:

    prefix func - (p : Point) -> Point {
        return Point(x : -p.x, y : -p.y)
    }

    也可用 postfix 重载后缀运算符:

    postfix func ++ (p : Point) -> Point {
        var px = p.x, py = p.y
        return Point(x : ++px, y : ++py)
    }

    甚至可以使用 operator 定义新的运算符:

    prefix operator %& {}
    prefix func %& (p : Point) -> Point {
        return Point(x : p.x % 8, y : p.y % 8)
    }

    C++ 中的运算符重载那是出了名的强大,甚至可以重载 IO 运算符,这里仅给出基本用法:

    class Point {
    public:
    	Point(int i1, int i2, int i3): x(i1), y(i2), z(i3){}
    	Point operator-();
    	Point operator++();
    	bool operator==(const Point &p);
    	Point operator+(const Point &p);
    	int operator[](size_t n);
    private:
    	int x, y, z;
    	int values[3] = {x, y, z};
    };
    
    Point Point::operator-() {
    	return Point(-x, -y, -z);
    }
    
    Point Point::operator++() {
    	return Point(++x, ++y, ++z);
    }
    
    bool Point::operator==(const Point &p) {
    	return x == p.x && y == p.y && z == p.z;
    }
    
    Point Point::operator+(const Point &p) {
    	return Point(x + p.x, y + p.y, z + p.z);
    }
    
    int Point::operator[](size_t n) {
    	return values[n];
    }
    
    int main (int argc, char **argv) {
    	Point p1(1, 3, 5);
    	Point p2(2, 4, 6);
    	std::cout << (p1 == p2 ? "p1 == p2" : "p1 != p2") << std::endl;
    	Point p3 = -(p1 + p2);
    	//p3.operator++();
    	++p3;
    	std::cout << "p3: " << p3[0] << ", " << p3[1] << ", " << p3[2] << std::endl;
    	return 0;
    }

    1.8  函数参数可设置是否可变:类似 C++

    C++ 中在函数前添加 const 即可声明为不可变,代码就不贴了。

    Swift 中函数参数默认就是不可变的,如果要在函数内部修改参数的值,需要在参数前声明 var 关键字:

    func printContactVar(var name: String, email : String) {
        name = name.uppercaseString
        printContact(name: name, email: email)
    }
    

    上面的 var 参数虽然能修改值,但作用域仅限于函数内部,如果想在函数调用结束后,在外部依然生效,还可将关键字改为 inout 

    1.9  函数参数可设置默认值:类似 C++

    Swift 中定义函数时,可设置参数默认值:

    func printContact(name : String = "Rinc", email : String = "i@RincLiu.com") {
        println("\(name): \(email)")
    }

    C++ 也有类似特性:

    void printContact(std::string name = "Rinc", std::string email = "i@RincLiu.com");
    void printContact(std::string name, std::string email) {
    	std::cout << name << ": " << email << std::endl;
    }

    1.91  可通过 count 和 repeatedValue 初始化数组:类似 C++

    Swift 版本:

    var a = [Character](count: 10, repeatedValue: "X")

    C++ 版本:

    std::vector<char> v(10, 'x');

    1.92  元组相关特性:类似 Golang

    Swift 中可以通过 不取元组中的某个元素:

    let people = ("Rinc", age : 25)
    var (name, _) = people

    还有用于集合数据的遍历:

    var dic : Dictionary<String, Int> = ["Rinc" : 25, "Emma": 24]
    for (k, _) in dic {
        println("\(k)")
    }

    Golang 由于经常取回的数据集含有索引(连数组都有),所以这种用法更常见:

    mp := map[string]float32{"C": 5, "GO": 4.5, "JAVA": 6}
    for key, _ := range mp {
    	fmt.Println(key)
    }

    虽然 C++11、Rust 等语言也支持元组,但感觉大多简单用于函数多值返回,像上面这种用法貌似没见过;

    1.93  其他特性

    1. 函数语句结束不加分号:Golang、Rust 等很多语言都支持;

    2.  var 动态类型声明:JavaScript、Golang 等语言都支持;

    3. 函数多值返回:因为有了元组的支持,所以实现这个并不难,C++、Golang、Rust 等语言都支持;

    4. 闭包:这东西现在随着函数式编程的热门,几乎所有语言都提供了支持,也不多说了。

    总结

    总体来看 Swift 吸收的 C++ 特性最多,其次是 Golang 和 Hashekll,还有少量 Rust 特性。

     

    2. Performance

    Swift 具有一门高效语言所需要具备的绝大部分特点。与 Ruby 或者 Python 这样的解释型语言不需要再做什么对比了,相较于其前辈的 Objective-C,Swift 在编译期间就完成了方法的绑定,因此方法调用上不再是类似于 Smalltalk 的消息发送,而是直接获取方法地址并进行调用。虽然 Objective-C 对运行时查找方法的过程进行了缓存和大量的优化,但是不可否认 Swift 的调用方式会更加迅速和高效。

    另外,与 Objective-C 不同,Swift 是一门强类型的语言,这意味 Swift 的运行时和代码编译期间的类型是一致的,这样编译器可以得到足够的信息来在生成中间码和机器码时进行优化。虽然都使用 LLVM 工具链进行编译,但是 Swift 的编译过程相比于 Objective-C 要多一个环节 -- 生成 Swift 中间代码 (Swift Intermediate Language,SIL)。SIL 中包含有很多根据类型假定的转换,这为之后进一步在更低层级优化提供了良好的基础,分析 SIL 也是我们探索 Swift 性能的有效方法。

    最后,Swift 具有良好的内存使用的策略和结构。Swift 标准库中绝大部分类型都是 struct,对值类型的 使用范围之广,在近期的编程语言中可谓首屈一指。原本值类型不可变性的特点,往往导致对于值的使用和修改意味着创建新的对象,但是 Swift 巧妙地规避了不必要的值类型复制,而仅只在必要时进行内存分配。这使得 Swift 在享受不可变性带来的便利以及避免不必要的共享状态的同时,还能够保持性能上的优秀。

    编译器优化

    Swift 编译器十分智能,它能在编译期间帮助我们移除不需要的代码,或者将某些方法进行内联 (inline) 处理。编译器优化的强度可以在编译时通过参数进行控制,Xcode 工程默认情况下有 Debug 和 Release 两种编译配置,在 Debug 模式下,LLVM Code Generation 和 Swift Code Generation 都不开启优化,这能保证编译速度。而在 Release 模式下,LLVM 默认使用 "Fastest, Smallest [-Os]",Swift Compiler 默认使用 "Fast [-O]",作为优化级别。我们另外还有几个额外的优化级别可以选择,优化级别越高,编译器对于源码的改动幅度和开启的优化力度也就越大,同时编译期间消 耗的时间也就越多。虽然绝大部分情况下没有问题,但是仍然需要当心的是,一些优化等级采用的是激进的优化策略,而禁用了一些检查。这可能在源码很复杂的情 况下导致潜在的错误。如果你使用了很高的优化级别,请再三测试 Release 和 Debug 条件下程序运行的逻辑,以防止编译器优化所带来的问题。

    值得一提的是,Swift 编译器有一个很有用的优化等级:"Fast, Whole Module Optimization",也即 -O -whole-module-optimization。在这个优化等级下,Swift 编译器将会同时考虑整个 module 中所有源码的情况,并将那些没有被继承和重载的类型和方法标记为 final,这将尽可能地避免动态派发的调用,或者甚至将方法进行内联处理以加速运行。开启这个额外的优化将会大幅增加编译时间,所以应该只在应用要发布的时候打开这个选项。

    虽然现在编译器在进行优化的时候已经足够智能了,但是在面对编写得非常复杂的情况时,很多本应实施的优化可能失效。因此保持代码的整洁、干净和简单,可以让编译器优化良好工作,以得到高效的机器码。

    3. 注释与换行

    注释

    请将你的代码中的非执行文本注释成提示或者笔记以方便你将来阅读。Swift 的编译器将会在编译代码时自动忽略掉注释部分。

    Swift 中的注释与C 语言的注释非常相似。单行注释以双正斜杠作(//)为起始标记:

    // 这是一个注释

    你也可以进行多行注释,其起始标记为单个正斜杠后跟随一个星号(/),终止标记为一个星号后跟随单个正斜杠(/):

    /* 这是一个, 多行注释 */

    与C 语言多行注释不同,Swift 的多行注释可以嵌套在其它的多行注释之中。你可以先生成一个多行注释块,然后在这个注释块之中再嵌套成第二个多行注释。终止注释时先插入第二个注释块的终止标记,然后再插入第一个注释块的终止标记:

    /* 这是第一个多行注释的开头 /* 这是第二个被嵌套的多行注释 */ 这是第一个多行注释的结尾 */

    通过运用嵌套多行注释,你可以快速方便的注释掉一大段代码,即使这段代码之中已经含有了多行注释块。

    4. Objective-C混合编程

    参考资料

    • 从Objective-C到Swift

    • swift与objective-c混编

    • Swift and Objective-C in the Same Project

    Swift 与 Objective-C混合调用示意图

    5. Swift类引用Objective-C文件

    因为Swift没有内嵌的头文件机制,因此Swift调用Objective-C需要一个名为“<工程名>-Bridging-Header.h”的桥接头文件。桥接头文件的作用是为Swift调用Objective-C对象搭建一个桥,它的命名必须是“<工程名>- Bridging-Header.h”,我们需要在桥接头文件中引入Objective-C头文件,所有的Swift类会自动引用这个头文件。

    桥接文件

    桥接文件设置

    • OJC类如下:

    //
    //  ObjcFunc.h
    //
    
    # import <Foundation/Foundation.h>
    
    @interface ObjcFunc : NSObject
    
    -(NSString*)sayHello:(NSString*)greeting withName: (NSString*)name;
    
    @end
    
    //
    //  ObjcFunc.m
    //
    
    # import "ObjcFunc.h"
    
    # import "CombinedProgram-Swift.h"
    
    @implementation ObjcFunc
    
    - (NSString*)sayHello:(NSString*)greeting withName: (NSString*)name{
    
        NSString *string = [NSString stringWithFormat:@"Hi,%@ %@.",name,greeting];
    
        return string;
    
      }
    
    @end
    • Swift类中调用

    import Foundation
    @objc class SwiftFunc: NSObject {
      func sayHello() -> Void {
      var obj : ObjcFunc = ObjcFunc()
      println(obj.sayHello("Hello", withName: "Swift"));
      return
      }
    }

    6. Objective-C类引用Swift文件

    (1)在Building Settings -> Packaging -> Defining中选定Module Name;

    (2)在OJC的头文件中引入:#import "{ModuleName}-swift.h"

    SwiftFunc* obj = [[SwiftFunc alloc] init];
    [obj sayHello];

    有时候会发现Xcode无法自动生成*-Swift.h文件,可以参考StackOverflow上的这篇文章。该文章总结下来,我们需要进行以下两大步检测:

    (1)检测你的Xcode的配置

    Product Module Name : myproject
    
    Defines Module : YES
    
    Embedded Content Contains Swift : YES
    
    Install Objective-C Compatibility Header : YES
    
    sObjective-C Bridging Header : $(SRCROOT)/Sources/SwiftBridging.h

    (2)检查你的Swift类是否正规

    要保证你的Swfit类中已经使用@objc关键字声明了一个继承自NSObject的类。Xcode不会为存在任何编译错误的类进行编译操作。

    (3)忽略Xcode的报错,先编译一下

    7. 语法要点

    ! VS ?

    在Swift中经常看到!与?两个操作符,譬如在类型转换、可选类型构造中都用到,用Apple官方的话说:

    It may be easiest to remember the pattern for these operators in Swift as: ! implies “this might trap,” while ?indicates “this might be nil.”

    就是!操作符表示我不管你编译器,我肯定要这么做,那么有可能导致运行时崩溃。而?操作符表示这个可能是nil,你帮我查查有没有进行完备的空检查。

    二. 以上是从语言技术角度,而如果从工程角度

    1, 生态环境比语言成熟慢:Swift非常适合思考,但是目前还不是工程化ready的语言,主要是上下游生态环境还不成熟,需要时间;

    2,路径依赖效应:人的路径依赖无解;未来使用swift并获得巨大市场成功的公司,不是今天这些市场上的巨无霸;就像诺基亚比苹果更早理解触屏的价值,但仍然只能眼睁睁看着苹果后来居上;普朗克曾经说过一句关于科学真理的真理,叙述为“一个新的科学真理取得胜利并不是通过让它的反对者们信服并看到真理的光明,而是通过这些反对者们最终死去,熟悉它的新一代成长起来。”对于技术来说也是如此。
     

    Reference

    Tutorial & Docs

    • 中文版 Apple 官方 Swift 教程《The Swift Programming Language》

    • Swift学习笔记

    Forum & Lessons

    Blog & News

    Book & Resources

    展开全文
  • Swift编程(中文版)

    2020-07-29 14:20:13
    Swift编程(中文版) .
  • swift4.1中文版

    2020-07-28 23:32:36
    swift4.1中文版
  • Swift 3 中的新特性

    万次阅读 2016-07-04 14:28:18
    原文:What’s New in Swift 3? 作者: Ben Morrow 译者:kmyhy Swift 3 将在下半年退出,对于 Swift 程序员来说,它带来了许多改变。 如果你没有密切关注 Swift Evolution 项目,那么在将代码迁移到 Swift 3 ...

    原文:What’s New in Swift 3?
    作者: Ben Morrow
    译者:kmyhy

    Swift 3 将在下半年推出,对于 Swift 程序员来说,它带来了许多改变。
    如果你没有密切关注 Swift Evolution 项目,那么在将代码迁移到 Swift 3 时,你可能不知道它到底有什么改变,以及它会对你的代码带来什么影响。那么你可能需要读一下这篇文章了。
    通过本文,我将重点介绍 Swift 3 中的重大改变,这些改变对你的代码有深刻影响。让我们开始吧!

    开始

    目前,Swift 3 仅在 Xcode 8 beta 版中有效。在未来几个月中,Swift 3 仍然在不断改变中,它还会发生一些变化。在 2016 年末,Xcode GM 发布时,Swift 3 的新特性才会固定下来。因此你应该沉住气,直到那个时候才可以向 App Store 提交用 Swift 3 编写的 app。
    为了便于开发者们将代码迁移到 Swift 3,苹果在 Xcode 8 中增加了一个 Swift 版本,即 Swift 2.3,对 Swift 作了一个小小的升级。如果你是一个开发者,Swift 2.3 和 2.2 实际并无不同,但 2.3 能够支持在 WWDC 中提到的新的 SDKs 和 Xcode 特性。在 Xcode 8 推出 beta 版时,你可以用 Swift 2.3 来提交你的 app,而不用将代码迁移到 Swift 3。
    我建议你在 Playground 中测试本文讨论的新特性,还可以用你某个项目来测试 Migration Assistant,以便你对这些改变有所了解。由于在 Xcode 8 beta 下一个版本及 Siwft 3 正式发布之前,你无法向 App Store 提交 app,你可以暂时不要讲代码迁移到 Swift 3,一直到这些问题得到解决。

    升级到 Swift 3

    在升级到 Swift 3 时,你会发现,基本上每个文件都需要改动!之所以这样,是因为所有的 Cocoa API 名称都被改变了。简而言之,API 仍然是原来的 API,但这个 API 在 Objective-C 中是一种叫法,而在 Swift 中又是另一种叫法了。Swift 3 语法书写起来要更贴近于自然语言。
    在 Xcode 8 中苹果提供了 Migration Assistant,它可以完成大部分的迁移工作。但很显然,仍然有一部分工作需要你手动完成。
    你可以立即将代码升级到 2.3 或者 3.0。如果你需要将代码又转回来,你可以用 Xcode 的 Edit > Convert > To Current Swift Syntax… 菜单。编译器会和 Migrateion Assistant 一样智能。如果你在调用方法时,偶然使用了老的 API,编译器会显示一个 Fixt-It 选项,让你使用正确的新 API。幸好 Swift 3 在最终发布时,才会停止改变源代码。因此,你可以将你的 Swift 代码保存为不同的版本。但是 Swift 核心团队不能保证这一点以后不会改变,如果在某个时候不在保证源码上的兼容,他们会提供一个较长的过渡期。这意味着源码是稳定的,这样能鼓励更多的保守的公司去使用它。
    这也说明,二进制稳定的目标还没有达到。本文最后将讨论这将导致的影响。

    已实现的 Swift Evolution 提议

    自从 Swift 开源以来,社区成员已经提交了超过 100 个改进建议。其中大部分(70多个)提议经过讨论修改之后已经被接受。还有一些仍然在激烈的争论之后被拒绝了。但最终,所有提议都要经过核心团队的最终拍板。
    核心团队和广大社区之间的合作是卓有成效的。事实上,Swift 在 Github 上获得了 30,000 多颗星。每周都会有新的提议提交,周周如此。甚至苹果的工程师也会在 Github 上提交他们的提议。

    在下一节中,你会看到一些类似 [SE-0001] 这样的标注。这是已经接受的提议编号,并且将在最终版的 Swift 3.0 中进行实现。每项提议都会标出,以便你查看每项改变的具体细节。

    API 的改变

    Swift 3 中最大的改变是标准库中在每个库中都采用了统一命名方式。API Design Guidleines中包含了这些规则,核心团队在构建 Swift 3 时采用了这些规则,对新手来说,这高度增强了可读性和易用性。核心团队遵循的是”好的 API 设计应当总是从调用者的角度看待问题“的原则。他们努力让 API 简单易用。不再多说,让我们开始介绍这些对你来说非常重要的改变。

    第一个参数的 label

    让我们从你每天都会在 Swift 中用到的例子开始。

    在函数或方法中的第一个参数现在必须有一个 label ,除非你显式地声明不要。以前,我们调用一个函数或方法时,可以忽略第一个参数的 label[SE-0046]:

    // 第一句是 Swift 2 语法,第二句是 Swift 3 语法
    
    "RW".writeToFile("filename", atomically: true, encoding: NSUTF8StringEncoding)
    "RW".write(toFile: "filename", atomically: true, encoding: NSUTF8StringEncoding)
    
    SKAction.rotateByAngle(CGFloat(M_PI_2), duration: 10)
    SKAction.rotate(byAngle: CGFloat(M_PI_2), duration: 10)
    
    UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline)
    UIFont.preferredFont(forTextStyle: UIFontTextStyleSubheadline)
    
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int
    override func numberOfSections(in tableView: UITableView) -> Int
    
    func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView?
    func viewForZooming(in scrollView: UIScrollView) -> UIView?
    
    NSTimer.scheduledTimerWithTimeInterval(0.35, target: self, selector: #selector(reset), userInfo: nil, repeats: true)
    NSTimer.scheduledTimer(timeInterval: 0.35, target: self, selector: #selector(reset), userInfo: nil, repeats: true)
    

    注意,有些方法使用介词“of”、“to”、“with”、“in”作为外部参数名。这是为了增加代码的可读性。

    如果这个方法不使用介词也不使用 label,你应该在方法定义时,显式地在第一个参数名之前加一个下划线:

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { ... }
    override func didMoveToView(_ view: SKView) { ... }

    在许多编程语言中,许多方法可以共用一个方法名,但参数名不同。Swift 也不例外,现在,你可以重载方法,APIs 能够将直接将它们转换成合适的调用。下面是一个例子,展示了 index() 方法的两种重载形式:

    let names = ["Anna", "Barbara"]
    if let annaIndex = names.index(of: "Anna") {
      print("Barbara's position: \(names.index(after: annaIndex))")
    }

    方法名是同一个,但参数名不同,这将让人更容易记忆。

    省略不必要的单词

    过去,在苹果标准库中,方法名中会包含一个单词,用于表明方法的返回值。因为 Swift 编译支持类型推断,这种做法其实并不必要。核心团队尽可能过滤一切“噪音”,因此将这些重复的单词都删除了,只留下方法名中最重要的部分。

    在将 Objective-C 库转换成本地 Swift 语言方面,API 变得更智能了[SE-0005]:

    // 第一句是 Swift 2 语法,第二句是 Swift 3 语法
    
    let blue = UIColor.blueColor()
    let blue = UIColor.blue()
    
    let min = numbers.minElement()
    let min = numbers.min()
    
    attributedString.appendAttributedString(anotherString)
    attributedString.append(anotherString)
    
    names.insert("Jane", atIndex: 0)
    names.insert("Jane", at: 0)
    
    UIDevice.currentDevice()
    UIDevice.current()

    新的 GCD 和 Core Graphics

    一提到遗留下来的“元老级” API,GCG 和 Core Graphics 更需要被重新“装扮一新”。

    Grand Central Dispatch 常用于长时间计算或者与服务器通讯。将任务放到不同的线程,你可以避免阻塞用户界面。libdispatch 库是用 C 语言编写的,提供了 C 风格的 API。这个 API 现在在 Swift 中被重新设计为[SE-0088]:

    // Swift 2 语法
    let queue = dispatch_queue_create("com.test.myqueue", nil)
    dispatch_async(queue) {
        print("Hello World")
    }
    
    // Swift 3 语法
    let queue = DispatchQueue(label: "com.test.myqueue")
    queue.async {
      print("Hello World")
    }

    类似的情况还有 Core Graphics。Core Graphics 是用 C 编写的,曾经以来一直只能以“丑陋”的函数方式调用。这是它的新的用法[SE-0044]:

    // Swift 2 语法
    let ctx = UIGraphicsGetCurrentContext()
    let rectangle = CGRect(x: 0, y: 0, width: 512, height: 512)
    CGContextSetFillColorWithColor(ctx, UIColor.blueColor().CGColor)
    CGContextSetStrokeColorWithColor(ctx, UIColor.whiteColor().CGColor)
    CGContextSetLineWidth(ctx, 10)
    CGContextAddRect(ctx, rectangle)
    CGContextDrawPath(ctx, .FillStroke)
    UIGraphicsEndImageContext()
    
    // Swift 3 语法
    if let ctx = UIGraphicsGetCurrentContext() {
        let rectangle = CGRect(x: 0, y: 0, width: 512, height: 512)
        ctx.setFillColor(UIColor.blue().cgColor)
        ctx.setStrokeColor(UIColor.white().cgColor)
        ctx.setLineWidth(10)
        ctx.addRect(rectangle)
        ctx.drawPath(using: .fillStroke)
    
        UIGraphicsEndImageContext()
    }

    枚举中 case 值的大小写

    另一个和过去的 Swift 代码不同的地方是,在枚举中定义的 case 值现在使用小驼峰命名法。这是为了和属性名或者变量名保持一致[SE-0006]:

    // 第一句是 Swift 2 语法,第二句是 Swift 3 语法
    UIInterfaceOrientationMask.Landscape
    UIInterfaceOrientationMask.landscape
    
    NSTextAlignment.Right
    NSTextAlignment.right
    
    SKBlendMode.Multiply
    SKBlendMode.multiply

    大驼峰命名法现在只在类型名和协议名上使用。当你习惯这一切之后,Swift 团队对于追求一致性的努力才没有白费。

    返回值的方法或者修改值的方法

    标准库中对方法名中使用动词和名词的规定也更加统一。你应当根据这个方法会导致什么后果或者要采取一些动作来进行方法命名。首要原则是如果这个方法名中包含“ed”或“ing”后缀,则表明这是一个名词。方法名为名词的方法有返回值。如果不包含这些后缀,则很可能这是一个动词。以动词命名的方法会对某块引用的内存进行一些操作。即所谓的“修改某个值”。下面是几个符合名词/动词命名规则的方法[SE-0006]:

    customArray.enumerate()
    customArray.enumerated()
    
    customArray.reverse()
    customArray.reversed()
    
    customArray.sort() // changed from .sortInPlace()
    customArray.sorted()

    下面是一些使用这些方法的代码片段:

    var ages = [21, 10, 2] // 变量,不是常量,这样你才能修改它
    ages.sort() // 修改值,现在值变成了 [2, 10, 21]
    
    for (index, age) in ages.enumerated() { // "-ed" 是名词,表示会返回一个 ages 拷贝
      print("\(index). \(age)") // 打印:1. 2 \n 2. 10 \n 3. 21
    }
    
    ###函数类型
    
    函数在声明和调用时,都需要用括号将参数括住:
    
    ```swift
    func f(a: Int) { ... }
    
    f(5)
    
    
    
    
    <div class="se-preview-section-delimiter"></div>
    

    但是,当你用函数类型作为参数时,你可能会写出这样的代码:

    func g(a: Int -> Int) -> Int -> Int  { ... } // Swift 2 语法
    
    
    
    
    <div class="se-preview-section-delimiter"></div>
    

    你会发现代码很难读懂。参数在哪里结束,返回值从哪里开始?在 Swift 3 中,正确的定义方法是[SE-0066]:

    func g(a: (Int) -> Int) -> (Int) -> Int  { ... } // new way, Swift 3
    
    
    
    
    <div class="se-preview-section-delimiter"></div>
    

    现在,参数列表被括号包裹,然后才是返回类型。事情变得简单,同时函数类型更容易被识别出来。通过下面的比照,你会更清楚:

    // Swift 2 语法
    Int -> Float
    String -> Int
    T -> U
    Int -> Float -> String
    
    // Swift 3 语法
    (Int) -> Float
    (String) -> Int
    (T) -> U
    (Int) -> (Float) -> String
    
    
    
    
    <div class="se-preview-section-delimiter"></div>
    

    API 的增强

    除了对已有 API 进行“旧瓶新装”这个最大的改变以外——有非常多的 Swift 社区正致力于此,也有对 Swift API 的一些功能上的增加。

    访问所属类型

    当你定义一个静态属性或方法时,你直接通过类或类型来调用它们:

    CustomStruct.staticMethod()
    
    
    
    
    <div class="se-preview-section-delimiter"></div>
    

    如果你当前正在编写类型内部的代码,你还是要使用类型名来调用静态方法。为了使表述更加清晰,现在你可以通过 Self 来引用当前实例所属类型。S 为大写的 Self 表示引用当前实例的类型,而 s 为小写的 self 则引用当前实例自身。

    这是具体的例子[SE-0068]:

    struct CustomStruct {
      static func staticMethod() { ... }
    
      func instanceMethod() {
        Self.staticMethod() // 在类型内部
      }
    }
    
    let customStruct = CustomStruct()
    customStruct.Self.staticMethod() // 在一个实例上应用类型
    
    
    
    
    <div class="se-preview-section-delimiter"></div>
    

    行内 Sequences

    sequence(first:next:) 以及 sequence(state:next:) 是全局函数,返回一个无限序列。你传给它们一个初值或一个可变的状态,它们会在稍后调用闭包中的代码[SE-0094]:

    for view in sequence(first: someView, next: { $0.superview }) {
        // someView, someView.superview, someView.superview.superview, ...
    }
    
    
    
    
    <div class="se-preview-section-delimiter"></div>
    

    还可以用 prefix 操作符来为序列加一个限制[SE-0045]:

    for x in sequence(first: 0.1, next: { $0 * 2 }).prefix(while: { $0 < 4 }) { 
      // 0.1, 0.2, 0.4, 0.8, 1.6, 3.2
    }

    杂项

    • #keyPath() 等同于 #selector() ,帮助你减少输入错误
    • 你可以在某些类型上调用 pi,比如:Float.pi、CGFloat.pi。大部分时候编译器能够推断出类型:let circumference = 2 * .pi * radius [SE-0067]
    • NS 前缀从老的 Foundation 类型中移除,现在可以用 Calendar、Date来替代 NSCalendar、NSDate 了

    工具的改善

    Swift 只是一门语言,大部分时候你都无法离开书写它的开发环境——对于苹果开发者来说,也就是 Xcode!工具上的改变影响着每天编写代码的方式。
    Swift 3 修正了编译器和 IDE 中的 Bug,还改善了报告错误和信息的精确性。就像你所期望的,每个版本的发布都会让 Swift 和编译器的运行变得更快:

    • 改善了字符串的 Hash 算法,导致在将字符串存入字典后,性能有 3 倍的提升
    • 将对象从堆移到栈中存放,导致性能有 24 倍的提升(某些情况下)
    • 编译器可以一次缓存多个文件(在整个模块被优化过的情况下)
    • 优化了代码的大小,导致 Swift 代码的编译尺寸更小。以苹果的 Demobots 为例,编译尺寸缩减了原大小的 77%。

    Xcode 也会更加智能地理解 Swift 代码:

    • 过去,当你在一个 API 方法比如 sort() 上右击并跳转到定义时,你会看到一个不太容易理解的头文件。现在,在 Xcode 8 中,你会看到 sort() 方法实际上是 Array 类的扩展。

    • Swift Snapshots 就如今晚发布的 Swift Evolution 所说。在完全合并到 Xcode 之前,Snapshots 提供了一个使用新语法的机会。Xcode 8 能够在 playgournd 中加载和运行 Swift Snapshots。

    Swift 包管理器

    开源后的 Swift 实际上包含了 Swift 语言本身、核心库和包管理器。这三者一起构成了我们所见到的 Swift。包管理器定义了一个简单的目录结构,其中包括了你所共享和导入到项目中的 Swift 代码。
    类似于你所用过 Cocoapods 或 Carthage 这些包管理器,Swift 包管理器会下载依赖项并编译它们,把它们 link 成库或可执行文件。已经有 1000 个库支持 Swift 包管理器,并且在未来几个月中,还会有更多的库支持它。

    计划中的特性

    前面说过,Swift 3 尽量避免不兼容的改变,从而使你的代码能够从一个版本与下一个版本兼容。如果这是真的,那么在这次发布中应该还有一些更远大的目标未能达到,即泛型增强(generic additions)和 ABI(程序二进制接口)稳定。
    泛型增强包括递归协议约束和能够将一个受约束的扩展符合新协议(例如,一个用于存放 Equatable 对象的数组也应当遵守 Equatable 协议)。在这些特性尚未实现之前,Swift 不能被视作 ABI 稳定的。
    ABI 稳定要求应用程序和库无论使用哪个版本的编译器编译,都能被 link 和能够彼此进行交互。这对于第三方库来说是个重要的进步,因为这样就可以不需要提供源码就可以封装出框架了,而现在新版本的 Swift 不但要这些第三方库修改代码,还要重新进行编译。
    此外,如果 ABI 稳定就可以移除包含在二进制文件中的 Swift 标准库,因为就目前来说 iOS 和 macOS app 都是用 Xcode 创建的。目前的二进制文件中包含有 2 MB 左右的文件大小是为了确保能够兼容未来的操作系统。
    总之,你现在只能保持源代码的版本兼容,而二进制版本的兼容当前仍然是不可能的。

    结尾

    Swift 仍然在不断演进,因为社区的目标是最佳实践。虽然它还很年轻,但它同时也面临着无比巨大的机遇和美好未来。Swift 现在已经能够在 Linux 上运行了,在未来几年,你还会看见它在更多的服务器和设备上运行。从头设计一门语言必然会破坏 ABI 稳定性,一旦等它稳定后这种破坏就变得小多了。这(开源)是唯一能够让这门语言变得更好的机会,否则我们必将后悔莫及。
    Swift 正在扩大它的影响力。苹果正在身体力行。苹果的团队们正在 Music app、Console、Sierra画中画、Xcode 文档查看器、新的 iPad 版的Swift Playground app 中使用 Swift。
    说到这里,苹果好像有一种让非程序员学习 Swift 意图,例如可以在 iPad 上使用 Swift 以及某些教育措施都表明了这一点。
    另外,Swift 正在持续改进:命名变得更规范,代码读起来更清晰,你可以用工具来迁移代码。如果你想进一步深入了解,请看 WWDC 的会议视频
    可以肯定的是,2016年末 Swift 3 的正式发布必将令人期待。我们将持续跟进所有改变,请继续关注我们的教程、新书预告和视频,我们将开始使用这些令人兴奋的改进。

    Swift 3 中最令你感到兴奋的特性是哪个?你最希望我们介绍的又是哪个?请在下面的留言中告诉我们。

    展开全文
  • 为何 iOS 越来越偏爱 Swift

    千次阅读 2018-10-25 00:37:45
    【CSDN编者按】本月初,苹果已经面向所有iPhone用户,推送了iOS 12.0.1正式版。那么,iOS 12.0中Swift的应用是个什么样子?iOS中使用Swift...
        

    640?wx_fmt=gif

    【CSDN编者按】本月初,苹果已经面向所有iPhone用户,推送了iOS 12.0.1正式版。那么,iOS 12.0中Swift的应用是个什么样子?iOS中使用Swift的二进制文件数目又有怎样的变化?一起来看今天的文章!

    640?wx_fmt=jpeg

    两年前我评估了苹果在iOS 10.1中Swift的应用情况,去年我评估了iOS 11.1中的应用情况。

    今年我来分析苹果这个月刚刚发布的iOS 12。


    640?wx_fmt=png

    方法


    本文使用的方法和工具在前面的文章里说过了。有兴趣的话可以参考这篇文章:苹果在iOS 10.1和macOS 10.12中对Swift的应用情况(https://blog.timac.org/2016/1101-apples-use-of-swift-in-ios-10-1-and-macos-10-12/)。


    640?wx_fmt=png

    iOS 12.0中Swift的应用


    下面是iOS 12.0中所有使用Swift的二进制文件。注意这些二进制文件可能只包含一行Swift代码,并不一定完全是用Swift写成的。我测试的是iPhone X中的iOS 12.0(16A366)。

    /Applications/ActivityMessagesApp.app/PlugIns/ActivityMessagesExtension.appex/ActivityMessagesExtension
    /Applications/AppStore.app/AppStore
    /Applications/AppStore.app/Frameworks/AppStoreKit.framework/AppStoreKit
    /Applications/AppStore.app/Frameworks/JetEngine.framework/JetEngine
    /Applications/AppStore.app/PlugIns/AppInstallExtension.appex/AppInstallExtension
    /Applications/AppStore.app/PlugIns/BridgeStoreExtension.appex/BridgeStoreExtension
    /Applications/AppStore.app/PlugIns/ProductPageExtension.appex/ProductPageExtension
    /Applications/BusinessExtensionsWrapper.app/PlugIns/Business.appex/Business
    /Applications/ContinuityCamera.app/ContinuityCamera
    /Applications/Diagnostics.app/Diagnostics
    /Applications/FTMInternal-4.app/FTMInternal-4
    /Applications/SharingViewService.app/SharingViewService
    /private/var/staged_system_apps/Books.app/Frameworks/AppAnalytics.framework/AppAnalytics
    /private/var/staged_system_apps/Calculator.app/Calculator
    /private/var/staged_system_apps/Files.app/Files
    /private/var/staged_system_apps/Files.app/PlugIns/RecentsWidget.appex/RecentsWidget
    /private/var/staged_system_apps/Measure.app/Measure
    /private/var/staged_system_apps/Music.app/Music
    /private/var/staged_system_apps/Music.app/PlugIns/MusicMessagesApp.appex/MusicMessagesApp
    /private/var/staged_system_apps/Music.app/PlugIns/PlaybackIntent.appex/PlaybackIntent
    /private/var/staged_system_apps/Music.app/PlugIns/RecentlyPlayedTodayExtension.appex/RecentlyPlayedTodayExtension
    /private/var/staged_system_apps/Podcasts.app/Frameworks/AppStoreKit.framework/AppStoreKit
    /private/var/staged_system_apps/Podcasts.app/Frameworks/NowPlayingUI.framework/NowPlayingUI
    /private/var/staged_system_apps/Podcasts.app/Frameworks/PodcastsUI.framework/PodcastsUI
    /private/var/staged_system_apps/Podcasts.app/Podcasts
    /private/var/staged_system_apps/Stocks.app/PlugIns/StocksToday.appex/StocksToday
    /private/var/staged_system_apps/Stocks.app/Stocks
    /System/Library/Accounts/DataclassOwners/StocksDataclassOwner.bundle/StocksDataclassOwner
    /System/Library/Accounts/Notification/DonationAccountWatcher.bundle/DonationAccountWatcher
    /System/Library/DistributedEvaluation/Plugins/StocksDES.desPlugin/StocksDES
    /System/Library/Frameworks/FileProvider.framework/PlugIns/LocalStorageFileProvider.appex/LocalStorageFileProvider
    /System/Library/Frameworks/IdentityLookup.framework/XPCServices/com.apple.IdentityLookup.MessageFilter.xpc/com.apple.IdentityLookup.MessageFilter
    /System/Library/Messages/iMessageBalloons/ASMessagesProvider.bundle/ASMessagesProvider
    /System/Library/PrivateFrameworks/ContactsDonation.framework/Versions/A/Support/contactsdonationagent
    /System/Library/PrivateFrameworks/CoreParsec.framework/parsec-fbf
    /System/Library/PrivateFrameworks/CoreParsec.framework/parsecd
    /System/Library/PrivateFrameworks/DocumentManagerUICore.framework/PlugIns/com.apple.DocumentManager.Service.appex/com.apple.DocumentManager.Service
    /System/Library/PrivateFrameworks/DocumentManagerUICore.framework/PlugIns/RecentsAppPopover.appex/RecentsAppPopover
    /System/Library/PrivateFrameworks/FMClient.framework/XPCServices/FMIPClientXPCService.xpc/FMIPClientXPCService
    /System/Library/PrivateFrameworks/Swift/libswiftDemangle.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftXCTest.dylib
    /System/Library/PrivateFrameworks/TelephonyUtilities.framework/callservicesd
    /System/Library/PrivateFrameworks/TelephonyUtilities.framework/PlugIns/PhoneIntentHandler.appex/PhoneIntentHandler
    /System/Library/PrivateFrameworks/UpNextWidget.framework/PlugIns/UpNext.appex/UpNext
    /usr/libexec/sharingd
    /usr/libexec/SidecarRelay
    /usr/libexec/tzd

    共享的dyld缓存还包含以下的二进制文件,大多数是Swift的库:

    /System/Library/PrivateFrameworks/ConversationKit.framework/ConversationKit
    /System/Library/PrivateFrameworks/CoreKnowledge.framework/CoreKnowledge
    /System/Library/PrivateFrameworks/FMClient.framework/FMClient
    /System/Library/PrivateFrameworks/News/Tea.framework/Tea
    /System/Library/PrivateFrameworks/News/TeaActivities.framework/TeaActivities
    /System/Library/PrivateFrameworks/News/TeaFoundation.framework/TeaFoundation
    /System/Library/PrivateFrameworks/News/TeaSettings.framework/TeaSettings
    /System/Library/PrivateFrameworks/News/TeaUI.framework/TeaUI
    /System/Library/PrivateFrameworks/Stocks/AppAnalytics.framework/AppAnalytics
    /System/Library/PrivateFrameworks/Stocks/NewsArticles.framework/NewsArticles
    /System/Library/PrivateFrameworks/Stocks/NewsFeed.framework/NewsFeed
    /System/Library/PrivateFrameworks/Stocks/StocksAnalytics.framework/StocksAnalytics
    /System/Library/PrivateFrameworks/Stocks/StocksCore.framework/StocksCore
    /System/Library/PrivateFrameworks/Stocks/StocksUI.framework/StocksUI
    /System/Library/PrivateFrameworks/Stocks/TeaActivities.framework/TeaActivities
    /System/Library/PrivateFrameworks/Stocks/TeaCharts.framework/TeaCharts
    /System/Library/PrivateFrameworks/Stocks/TeaDB.framework/TeaDB
    /System/Library/PrivateFrameworks/Stocks/TeaFoundation.framework/TeaFoundation
    /System/Library/PrivateFrameworks/Stocks/TeaSettings.framework/TeaSettings
    /System/Library/PrivateFrameworks/Stocks/TeaTemplate.framework/TeaTemplate
    /System/Library/PrivateFrameworks/Stocks/TeaUI.framework/TeaUI
    /System/Library/PrivateFrameworks/Swift/libswiftAccelerate.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftARKit.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftAssetsLibrary.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftAVFoundation.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftCallKit.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftCloudKit.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftContacts.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftCore.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftCoreAudio.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftCoreData.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftCoreFoundation.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftCoreGraphics.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftCoreImage.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftCoreLocation.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftCoreMedia.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftDarwin.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftDispatch.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftFoundation.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftGameplayKit.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftGLKit.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftHomeKit.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftIntents.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftMapKit.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftMediaPlayer.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftMetal.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftMetalKit.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftModelIO.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftNaturalLanguage.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftNetwork.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftObjectiveC.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftos.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftPhotos.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftQuartzCore.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftSceneKit.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftsimd.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftSpriteKit.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftSwiftOnoneSupport.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftUIKit.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftVision.dylib
    /System/Library/PrivateFrameworks/Swift/libswiftWatchKit.dylib


    640?wx_fmt=png

    结论


    苹果在iOS 12中添加了一些新功能,预料之中的是,这些应用都会包含一些Swift代码。比如Continuity Camera和Measure应用就是如此。

    以前的应用被更新过,一些也包含了更多的Swift代码,如AppStore、Books、Music、News、SharingViewService和Stocks。

    可以看到,每次新的iOS发布,苹果都在越来越多的应用中使用Swift,但这些应用的总数依然很有限。下面这张图显示了iOS中使用Swift的二进制文件数目的增长(不含Swift库):

    640?wx_fmt=png

    原文:https://blog.timac.org/2018/0924-state-of-swift-ios12/

    译者:弯月,责编:胡巍巍

    推荐阅读:

    640?wx_fmt=gif

    640?wx_fmt=gif

    展开全文
  • 国际结算三大方式之——汇款

    万次阅读 2016-11-11 08:55:23
    汇款(Remittance)业务是国际结算方式之一,帮助客户实现资金的转移。汇款分为汇出汇款和汇入汇款两种,银行间不涉及单据...当前汇款主要采取的方式通过电汇(TelegraphicTransfer,T/T),通过Swift系统实现,一般2
  • 在Windows下编写swift程序

    千次阅读 2020-03-03 18:45:47
    在Windows下编写swift程序 1.首先介绍一下本次使用到的软件Visual Studio Code和 Swift for Windows(见图1)。 Visual Studio Code(以下简称vscode)是一个轻量且强大的跨平台开源代码编辑器(IDE),支持Windows...
  • 掌握ios基本组件使用,熟悉众多技巧
  • swift 中 把 String转成Int或Double。。。
  • 使用swift有一段时间了,api的变换造成了很多困扰,下面是关于url编码和解码问题的解决方案 在Swift中URL编码encode在Swift中URL编码用到的是String的方法func addingPercentEncoding(withAllowedCharacters ...
  • iOS OC项目调用Swift

    万次阅读 2017-03-17 13:51:27
    网上有很多关于OC项目中使用Swift类的方法,但是亲自试了之后,发现不够详细,多次尝试后,终于找出详细的方法。 现把方法和遇到的问题,记录下来,方便其他同仁借鉴.
  • swift 学习资源 大集合

    万次阅读 2014-06-07 17:07:46
    今天看到了一个swift的学习网站,里面收集了很多学习资源 Swift 介绍 Swift 介绍  来自 Apple 官方 Swift 简介 (@peng_gong)  一篇不错的中文简介 [译] Swift 首席架构师 Chris Lattner ...
  • 爆炸性新闻
  • 掌握apple watch上的开发
  • Swift 获得字符串String长度

    万次阅读 2020-02-19 16:17:39
    在Objective-C中我们通常使用length来获取NSString类型的字符串的长度,而在Swift中,String结构体没有了这个方法,那怎样获取String类型的字符串的长度呢?我们可以通过他的扩展属性成员characters的count属性来获取 ...
  • Swift String转化为Float、Int

    万次阅读 2017-01-12 15:27:09
    使用类型Float强制转换 Float(String) 而CGFloat 无法这样做!
  • 掌握iOS基本组件的使用
1 2 3 4 5 ... 20
收藏数 144,630
精华内容 57,852
关键字:

swift