您的位置:新葡亰496net > 奥门新萄京娱乐场 > Swift3新特征汇总,的某些有别于

Swift3新特征汇总,的某些有别于

发布时间:2019-07-05 12:57编辑:奥门新萄京娱乐场浏览(59)

    后面 Apple 在 WWDC 桐月将 Swift 3 整合进了 Xcode 8 beta 中,而上一个月苹果公布了 斯维夫特 3 的正式版。那也是自 2016年终Apple开源Swift之后,第三个发表的主要版本(Swift 3.0),该版本达成了 斯威夫特 衍变进度中所商讨并由此的90多少个指出。这里小编对 Swift 3 的新性格、新变化举办三个总计。

    一、通透到底移除在 斯维夫特 2.2 就曾经弃用的风味

    那么些特点在我们采纳 Xcode 7.3 的时候就已经有报告警察方提示,在 斯维夫特 3 中已将其到底移出。
    1、弃用 与 -- 操作符

    过去我们得以选用 与 -- 操作符来贯彻自增自减,现已扬弃。

    var i = 0 
    i  
      i
    i--
    --i
    

    能够选用复合加法运算( =)与减法运算(-=),可能应用普通的加法运算( )与减法运算(-)达成平等的职能。
    2、撤除C语言风格的for循环
    我们过去只怕习于旧贯上边风格的 for 循环,今后也已屏弃。
    今昔能够运用 for-in 循环,恐怕应用 for-each 加闭包的写法达成平等的功用。

    //for-in循环for i in 1...10 {
        print(i)
    }
    //for-each循环(1...10).forEach {
        print($0)
    }
    

    3、移除函数参数的 var 标记
    在 斯维夫特 函数中,参数暗许是常量。过去得以在参数前加关键字 var 将其定义为变量,那样函数内部就能够对该参数实行改造(外界的参数任然不会被改换)。

    var age = 22
    add(age)
    func add(var age:Int) {
        age  = 1
    }
    

    今天这种做法早已被屏弃,斯威夫特 3 不再允许开荒者那样来将参数标志为变量了。
    4、全部函数参数都无法不带上标签
    千古假设贰个函数有七个参数,调用的时候第一个参数无需带标签,而从第三个参数初步,绝对要带标签。

    let number = additive(8, b: 12)
    func additive(a:Int, b:Int) -> Int{
       return a   b
    }
    

    当今为了保证函数参数标签的一致性,全部参数都必须带上标签。

    let number = additive(a: 8, b: 12)
    func additive(a:Int, b:Int) -> Int{ 
       return a   b
    }
    

    本条调换恐怕会导致大家的品种代码要开始展览十分大的更改,终归涉及的地点重重。所以苹果又交给了一种不用给第三个参数带标签的缓慢解决方案。即在首先个参数前边加上贰个下划线。(不过那么些只是低价我们代码从 斯维夫特2 迁移到 Swift3 的五个折中方案,可以的话依旧提议将全部的参数都带上标签。)

    let number = additive(8, b: 12)
    func additive(_ a:Int, b:Int) -> Int{
        return a   b
    }
    

    5、函数评释和函数调用都急需括号来总结参数
    ****咱俩得以运用函数类型作为参数 ,对于叁个参数是函数、重回值也是函数的函数。原本小编们大概会如此写:

    func g(a: Int -> Int) -> Int->Int { ... }
    

    当如此丰盛难以阅读,非常难看出参数在哪儿结束,再次回到值又从何地开首。在 斯维夫特3 中成为那样定义这么些函数:

    func g(a:(Int) -> Int) -> (Int) -> Int { ... }
    

    6、Selector 不再允许使用 String
    假使大家给开关加多一个点击事件响应,点击后举办 tapped 函数。从前可以如此写:

    button.addTarget(responder, action: "tapped", forControlEvents: .TouchUpInside)
    

    但出于开关的 selector 写的是字符串。要是字符串拼写错了,那程序会在运作时因找不到相关办法而夭亡。所以 斯威夫特 3 将这种写法取消,改成 #selecor()。这样就将同意编写翻译器提前检查措施名的拼写难题,而不用再等到运转时才发掘难点。

    button.addTarget(self, action:#selector(tapped), for:.touchUpInside)
    

    二、斯维夫特 3 的新特色

    1、内联连串函数sequence
    ****斯威夫特 3 新扩大了多个全局函数:sequence(first: next:) 和 sequence(state: next:)。使用它们得以回到多个不过种类。

    // 从某一个树节点一直向上遍历到根节点
    for node in sequence(first: leaf, next: { $0.parent }) {  
      // node is leaf, then leaf.parent, then leaf.parent.parent, etc.
    }
    // 遍历出所有的2的n次方数(不考虑溢出)
    for value in sequence(first: 1, next: { $0 * 2 }) { 
       // value is 1, then 2, then 4, then 8, etc.
    }
    

    2、 key-path不再只好利用String
    那些是用在键值编码(KVC)与键值观望(KVO)上的,具体 KVC、KVO 相关内容可以参照笔者本来写的那篇小说:Swift - 反射(Reflection)的介绍与行使样例(附KVC介绍)大家仍是能够一而再使用 String 类型的 key-Path:

    //用户类
    class User: NSObject{ 
       var name:String = ""  //姓名   
       var age:Int = 0  //年龄
    }
    //创建一个User实例对象
    let user1 = User()
    user1.name = "hangge"
    user1.age = 100
    //使用KVC取值
    let name = user1.value(forKey: "name")
    print(name)
    //使用KVC赋值
    user1.setValue("hangge.com", forKey: "name")
    

    但建议选择新扩大的 #keyPath() 写法,那样能够制止大家因为拼写错误而引发难点。

    //使用KVC取值
    let name = user1.value(forKeyPath: #keyPath(User.name))print(name)
    //使用KVC赋值
    user1.setValue("hangge.com", forKeyPath: #keyPath(User.name))
    

    3、Foundation 去掉 NS 前缀
    比如过去我们选择 Foundation 相关类来对文件中的 JSON 数据举行辨析,这么写:

    let file = NSBundle.mainBundle().pathForResource("tutorials", ofType: "json")
    let url = NSURL(fileURLWithPath: file!)
    let data = NSData(contentsOfURL: url)
    let json = try! NSJSONSerialization.JSONObjectWithData(data!, options: [])
    print(json)
    

    在 斯维夫特 3 中,将移除 NS 前缀,就改为了:

    let file = Bundle.main.path(forResource: "tutorials", ofType: "json")
    let url = URL(fileURLWithPath: file!)
    let data = try! Data(contentsOf: url)
    let json = try! JSONSerialization.jsonObject(with: data) 
    print(json)
    

    4、除了M_PI 还有 .pi
    在过去,大家采取 M_PI 常量来代表 π。所以依据半径求周长代码如下:

    let r = 3.0
    let circumference = 2 * M_PI * r
    

    在 Swift 3 中,π 提供了 Float,Double 与 CGFloat 两种样式(Float.pi、Double.pi、CGFloat.pi),所以求周长还足以那样写:

    let r =  3.0
    let circumference = 2 * Double.pi * r
    //我们还可以将前缀省略,让其通过类型自动推断
    let r = 3.0
    let circumference = 2 * .pi * r
    

    5、简化GCD的写法
    有关 GCD,笔者原本写过一篇有关小说:Swift - 二十三十二线程完结格局(3) - Grand Central Dispatch(GCD)过去写法接纳 C 语言的品格,初学者可能会相当的小适应。比方创造两个总结的异步线程:

    let queue = dispatch_queue_create("Swift 2.2", nil)
    dispatch_async(queue) {
        print("Swift 2.2 queue")
    }
    

    Swift 3 撤销了这种冗余的写法,而利用了特别面向对象的格局:

    let queue = DispatchQueue(label: "Swift 3")
    queue.async {
        print("Swift 3 queue")
    }
    

    6、Core Graphics的写法也愈加面向对象化
    Core Graphics 是三个一定庞大的绘图框架,不过和 GCD 同样,它原来的 API 也是 C 语言风格的。比如大家要创制二个 view,其内部背景使用 Core Graphics 实行绘图(豆灰边框,牡蛎白背景)。过去大家如此写:

     class View: UIView {
        override func drawRect(rect: CGRect) {
            let context = UIGraphicsGetCurrentContext()
            let blue = UIColor.blueColor().CGColor 
           CGContextSetFillColorWithColor(context, blue)
            let red = UIColor.redColor().CGColor 
           CGContextSetStrokeColorWithColor(context, red)
            CGContextSetLineWidth(context, 10)
            CGContextAddRect(context, frame) 
           CGContextDrawPath(context, .FillStroke)
        }}
    let frame = CGRect(x: 0, y: 0, width: 100, height: 50)let aView = View(frame: frame)
    

    在 Swift 3 中改革了写法,只要对现阶段画布上下文解包,之后的具有绘制操作就都基于解包对象。

    class View: UIView {
        override func draw(_ rect: CGRect) {
            guard let context = UIGraphicsGetCurrentContext() else {
                return
            } 
           let blue = UIColor.blue.cgColor
            context.setFillColor(blue)
            let red = UIColor.red.cgColor
            context.setStrokeColor(red)
            context.setLineWidth(10)
            context.addRect(frame)
            context.drawPath(using: .fillStroke)
        }}
    let frame = CGRect(x: 0, y: 0, width: 100, height: 50)
    let aView = View(frame: frame)
    

    7、新添的采访调节关键字:fileprivate、open
    在 斯威夫特 3 中在原本的 3 个访问调控关键字 private、public、internal 外。又增添了2个新注重字 fileprivate、open。它们能够作为是对原先 private 和 public 的更为划分。具体应用方法和介绍能够看本人写的另一篇小说:Swift

    • 斯威夫特3新扩充的八个访谈调整关键字介绍(fileprivate、open)
      三、一些语法的更换

    1、数组排序:sort()与sorted()
    千古数组排序的多个方式:sortInPlace() 和 sort(),未来个别更名成 sort() 和 sorted()sort() 是一向对指标数组实行排序。sorted() 是回来三个排序后的数组,原数组不改变。

     var array1 = [1, 5, 3, 2, 4]
    array1.sort()print(array1)//[1, 2, 3, 4, 5]
    var array2 = [1, 5, 3, 2, 4]
    let sortedArray = array2.sorted()print(array2)  //[1, 5, 3, 2, 4]
    print(sortedArray)  //[1, 2, 3, 4, 5]
    

    2、reversed()与enumerated()
    过去 reverse() 方法实现数组反转,enumerate() 方法达成遍历。现这多个艺术都增加 ed 后缀(reversed、enumerated)

    for i in (1...10).reversed() {
        print(i)
    }
    let array = [1, 5, 3, 2, 4]
    for (index, value) in array.enumerated() {
        print("(index   1) (value)")
    }
    

    3、CGRect、CGPoint、CGSize
    过去的 CGRectMake、CGPointMake、CGSizeMake 已废弃。现改用 CGRect、CGPoint、CGSize 代替。

    //Swift 2
    let frame = CGRectMake(0, 0, 20, 20)
    let point = CGPointMake(0, 0)
    let size = CGSizeMake(20, 20)
    //Swift 3
    let frame = CGRect(x: 0, y: 0, width: 20, height: 20)
    let point = CGPoint(x: 0, y: 0)
    let size = CGSize(width: 20, height: 20)
    

    4、移除了API中剩下的单词

    XCPlaygroundPage.currentPage 改为 PlaygroundPage.current
    button.setTitle(forState) 改为 button.setTitle(for)
    button.addTarget(action, forControlEvents) 改为 button.addTarget(action, for)
    arr.minElement() 改为 arr.min()
    arr.maxElement() 改为 arr.max()
    attributedString.appendAttributedString(anotherString) 改为 attributedString.append(anotherString)
    names.insert("Jane", atIndex: 0) 改为 names.insert("Jane", at: 0)
    NSBundle.mainBundle() 改为 Bundle.main
    UIDevice.currentDevice() 改为 UIDevice.current
    NSData(contentsOfURL) 改为 Data(contentsOf)
    NSJSONSerialization.JSONObjectWithData() 改为 JSONSerialization.jsonObject(with)
    UIColor.blueColor() 改为 UIColor.blue

    5、枚举成员成为小写字母开始
    斯维夫特 3 将枚举成员当做属性来看,所今后后利用小写字母开端而不是先前的大写字母。

    .system
     //过去是:
    .System.touchUpInside 
    //过去是:
    .TouchUpInside.fillStroke 
    //过去是:
    .FillStroke.cgColor
     //过去是:
    .CGColor
    

    6、@discardableResult
    在 斯威夫特 3 中,假设五个格局有重返值。而调用的时候从不接受该方式的重临值,Xcode 会报出警告,告诉您那大概会设有潜在难点。!

    图片 1

    7B0CDB34-A690-435C-9933-060BBD7D5938.png

    除此之外可以通过接收重返值消除警告。仍是可以够透过给艺术评释 @discardableResult 来达成解除目标。

    .system //过去是:
    .System.touchUpInside
     //过去是:
    .TouchUpInside.fillStroke 
    //过去是:
    .FillStroke.cgColor 
    //过去是:
    .CGColorimport 
    UIKit
    class ViewController: UIViewController { 
       override func viewDidLoad() { 
           super.viewDidLoad() 
           printMessage(message: "Hello Swift 3!")
        }
        @discardableResult
        func printMessage(message: String) -> String {
            let outputMessage = "Output : (message)"
            return outputMessage    }
        override func didReceiveMemoryWarning() { 
           super.didReceiveMemoryWarning()
        }
    }
    

    7、斯维夫特赋值运算符,溢出运算符, 空合併运算符 ??

            /**
             赋值运算符
             =     =  %=  *=  /=
             本质上是对内存的写操作
             */
    
            let b = 10
            var a = 9
            var d:Int
    
            a = 6
            // c语言中可以这样子,但是 在swfit中 表达式 a = 6 是没有值的
            // 在[Swift](http://lib.csdn.net/base/swift)中禁止连续赋值
            //        d = a = 6
    
            print("a的值(a)")
            print("a = 6表达式的值==(a = 6)")
    
            // 加括号的连续赋值都不行的呀
    //                 d = (a  = 6)
    
    
    
    
    
    
            /**
             像这种就会报错的
             因为[swift](http://lib.csdn.net/base/swift)的赋值操作并不返回任何值。
             这个特性防止程序员将 c == 6 的判断误写成 c = 6,减少了常规的编码错误
             Use of '=' in a boolean context, did you mean '=='?
             */
    //        if c = 6 {
    //            print("lalla")
    //        }
    
    
    
            /**
             溢出运算符  &  &-  &*
             */
            var c = UInt8.min
    
            /**
             Arithmetic operation '0 - 1' (on type 'UInt8') results in an overflow
             */
    //        c = c - 1
            c = c &- 1
            print("c==(c)")
            /**
             c==255
             */
    
    
            /**
             Swift中可以 对浮点数求余
             */
    
            /**
             '%' is unavailable: Use truncatingRemainder instead
             现在不可以直接这样写了
             let rem = 10 % 2.3
             */
            let rem = CGFloat(10).truncatingRemainder(dividingBy: 2.3);
            print("rem==(rem)")
            /**
             rem==0.800000000000001
             remainderA is '1.0'.
             remainderB is '2.1'.
             */
    
    
            var remainderA = CGFloat(3).truncatingRemainder(dividingBy: 2);
            print("remainderA is '(remainderA)'.") // 输出 remainderA is '1'
    
            var remainderB = CGFloat(5.2).truncatingRemainder(dividingBy: 3.1)
            print("remainderB is '(remainderB)'.") // 输出 remainderB is '2.1'
    
    
    
    
    
             /**
             空合并运算符  (a ?? b) 将对可选类型a进行空判断,如果a包含一个值就进行解封,否则就返回一个默认值b。
             两个条件:表达式a必须是可选类型,默认值b的类型必须要和a存储值的类型一致
    
             在 Swift中有一个非常有用的操作符,可以用来快速的对 nil 进行判断。
             ??
             这个操作符可以判断当左侧的值是 非 nil时 Optional值时返回其value,
             左侧为nil时返回其右侧的值。比如
             */
            var level: Int?
            var startLevel = 1
    
            var currentLevel = level ?? startLevel
            print("currentLevel==(currentLevel)")
    
            let name: String? = "老王"
            let name1: String? = nil
    
            // ?? 运算符的优先级低于   号,注意使用的时候加上括号啊
            print(name ?? ""   "你好")
            print(name1 ?? ""   "你好")
    
    
    
            addNumber(x: 3, y: nil)
    
    
        func addNumber(x: Int?, y: Int?) -> Void {
    
            // 1.强制解包有风险
    //        print(x!   y!)
    
    
            // 2.使用 if 判断,但是如果直接使用if,参数很多的时候,会使代码很丑
            if x != nil && y != nil {
                print(x!   y!)
            } else {
                print("x 或者 y 为nil")
            }
    
            // 使用 运算符 ??
            print((x ?? 0)   (y ?? 0))
        }
    

    在Swift 2.0 中调用函数和艺术已经做出了改观,在3.0中又爆发了变动,而这一遍的改换则是根本的、屏弃旧笔者的!在Swift2.0及以前的格局名是没有必要为第多少个参数设置标签的,所以首先个参数名称日常会停放到方式名称的末尾,举例:

    names.indexOf("Taylor")
    "Taylor".writeToFile("filename", atomically:true, encoding:NSUTF8StringEncoding)
    SKAction.rotateByAngle(CGFloat(M_PI_2), duration:10)
    UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline)
    overridefuncnumberOfSectionsInTableView(tableView:UITableView) ->IntfuncviewForZoomingInScrollView(scrollView:UIScrollView) ->UIView?
    NSTimer.scheduledTimerWithTimeInterval(0.35, target:self, selector:#selector(createEnemy), userInfo:nil, repeats:true)
    

    在斯维夫特3.0中负有的富有的标签都是必须的,那也就意味着着艺术名不再含有参数的一部分。在实操中,正是艺术名的终极一片段被移入到了括号之中。

    names.indexOf("Taylor")
    names.index(of:"Taylor")
    
    "Taylor".writeToFile("filename", atomically:true, encoding:NSUTF8StringEncoding)
    "Taylor".write(toFile:"somefile", 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(createEnemy), userInfo:nil, repeats:true)
    NSTimer.scheduledTimer(timeInterval:0.35, target:self, selector:#selector(createEnemy), userInfo:nil, repeats:true)
    

    但,还是有一对相关反应的章程:当咱们连接受框架的时候,举例UIKit,那个点子希望在 Swift 3.0 中可能沿用旧有的“无第一参数名”的条条框框。在Swift 2.2 中:

    override func viewWillAppear(animated:Bool)
    
    override func tableView(tableView:UITableView, numberOfRowsInSection section:Int) ->IntoverridefuncdidMoveToView(view:SKView)
    
    override func traitCollectionDidChange(previousTraitCollection:UITraitCollection?)
    
    func textFieldShouldReturn(textField:UITextField) ->Bool
    

    在 斯威夫特3.0中,他们都亟需在率先参数前使用下划线标志它们接纳ObjC代码,而不使用参数标签。

    override func viewWillAppear(_animated:Bool)
    
    override func tableView(_tableView:UITableView, numberOfRowsInSection section:Int) ->Int
    
    override func didMoveToView(_view:SKView)
    
    override func traitCollectionDidChange(_previousTraitCollection:UITraitCollection?)
    
    func textFieldShouldReturn(_textField:UITextField) ->Bool
    

    忽略不必要的词

    当Swift在2014年10月被开源的时候,全新的API指点布置包蕴了八个要命的词:“忽略 不必要 词语”,它引进了Swift 3.0 中另贰个高大的退换,因为在措施名中这么些根本未曾须求出现的辞藻将被移去。让我们看上边包车型客车这几个swift 2.第22中学的代码:

    letblue = UIColor.blueColor()
    
    letmin = numbers.minElement()
    
    attributedString.appendAttributedString(anotherString)
    
    names.insert("Jane", atIndex:0)
    
    UIDevice.currentDevice()
    

    能见到代码中的难点呢?当大家运用UIColor的时候,blue当然是二个颜色,所以使用blueColor是剩下的。当大家增添三个属性字符串到另三个的时候,那三个东东必定都是字符串,而不大概另三个是“大象”对吗!所以,同样的代码在斯威夫特3.0中便是:

    letblue = UIColor.blue()
    
    letmin = numbers.min()
    
    attributedString.append(anotherString)
    
    names.insert("Jane", at:0)
    
    UIDevice.current()
    

    正如你看来的,这一个改动让艺术名称越来越短了。
    这种变动在字符串的操作上效果显然,比较上面包车型大巴代码,你会发觉斯威夫特2.2和Swift 3.0里面,大家写入的代码真是少了。

    "  Hello  ".stringByTrimmingCharactersInSet(.whitespaceAndNewlineCharacterSet())
    "  Hello  ".trimmingCharacters(in: .whitespacesAndNewlines())
    
    "Taylor".containsString("ayl")
    "Taylor".contains("ayl")
    
    "1,2,3,4,5".componentsSeparatedByString(",")
    "1,2,3,4,5".componentsSeparated(by:",")
    
    myPath.stringByAppendingPathComponent("file.txt")
    myPath.appendingPathComponent("file.txt")
    
    "Hello, world".stringByReplacingOccurrencesOfString("Hello", withString:"Goodbye")
    "Hello, world".replacingOccurrences(of:"Hello", with:"Goodbye")
    
    "Hello, world".substringFromIndex(7)
    "Hello, world".substring(from:7)
    
    "Hello, world".capitalizedString
    "Hello, world".capitalized
    

    留心:capitalized 如故是三个本性,可是lowercaseString 和 uppercaseString 面目全非成为艺术 lowercased() 和 uppercased()了。

    再有一个Swift 3.0的不二秘籍是底下那样:
    dismiss(animated:true, completion:nil)

    您大概会想,大家要dismiss什么吗?Swift3.0是既要增多第一参数的竹签,又要去除不须求的词,所以地点的代码实际是Swift2.第22中学的

    dismissViewControllerAnimated(true, completion:nil)
    

    怀有同等效果的还也会有prepareForSegue方法,在斯维夫特 3.0 中它产生了这么:

    overridefuncprepare(forsegue:UIStoryboardSegue, sender:AnyObject?)
    

    对此枚举和性格,驼峰大写前缀被替换到了驼峰小写前缀

    虽说与语法未有怎么关联,然则我们对此类、结构、属性和枚举,始终遵照着一个约定:类、结商谈枚举使用驼峰大写前缀,属性和参数名称使用驼峰小写前缀。那些约定也是有两样,使用NSUENVISIONLRequest(U翼虎L: someUTiggoL) 创立NSUKoleosLRequest对象的时候,参数正是大写U中华VL。斯维夫特3重写了该办法为NSUOdysseyLRequest(url: someUEnclaveL) ,也意味我们将会利用webView.request?.url?.absoluteString格局来读取web view的U大切诺基L。

    再有局地是在性质部分,比如说CGColor或CIColor。是的,未来它将会化为cgColor和ciColor。

    letred = UIColor.red().cgColor
    

    这种变化实在提升了编码的一致性:全体的习性和参数应该都以以小写起来,未有分裂!

    再正是,枚举也在发生着退换,从驼峰大写前缀改为驼峰小写前缀。那意味着:枚举是三个数据类型,不过枚举值更仿佛属性。然则,那象征苹果的枚举未来都以小写了。

    UIInterfaceOrientationMask.Portrait// old
    UIInterfaceOrientationMask.portrait// new
    
    NSTextAlignment.Left// old
    NSTextAlignment.left// new
    
    SKBlendMode.Replace// old
    SKBlendMode.replace// new
    

    Swift 引入 C 函数

    斯威夫特3引进C函数的习性。比如,全部以CGContext起头的函数以后都被映射为CGContext对象上的品质方法,那样大家就能够不再行使令大家充裕伤心的CGContextSetFillColorWithColor()函数了。

    swift 2.第22中学的代码:

    let ctx = UIGraphicsGetCurrentContext()
    let rectangle = CGRect(x:0, y:0, width:512, height:512)
    CGContextSetFillColorWithColor(ctx, UIColor.redColor().CGColor)
    CGContextSetStrokeColorWithColor(ctx, UIColor.blackColor().CGColor)
    CGContextSetLineWidth(ctx,10)
    CGContextAddRect(ctx,rectangle)
    CGContextDrawPath(ctx, .FillStroke)
    UIGraphicsEndImageContext()
    

    在斯维夫特 3.0中CGContext被用作指标管理,咱们得以一向调用方法了。

    if let ctx = UIGraphicsGetCurrentContext() {
      letrectangle = CGRect(x:0, y:0, width:512, height:512)
      ctx.setFillColor(UIColor.red().cgColor)
      ctx.setStrokeColor(UIColor.black().cgColor)
      ctx.setLineWidth(10)
      ctx.addRect(rectangle)
      ctx.drawPath(using: .fillStroke)
      UIGraphicsEndImageContext()
    }
    

    瞩目:不管是Swift 2.2还是斯维夫特 3.0 UIGraphicsGetCurrentContext()再次来到的是可选CGContext,所以在Swift3.0中应用CGContext对象的办法,必须先拆包。

    C函数映射也存在于另外地方,举例读取CGPDFDocument的numberOfPages属性和CGAffineTransform。上面是新旧代码比较:

    CGAffineTransformIdentity
    CGAffineTransform.identity
    
    CGAffineTransformMakeScale(2,2)
    CGAffineTransform(scaleX:2, y:2)
    
    CGAffineTransformMakeTranslation(128,128)
    CGAffineTransform(translationX:128, y:128)
    
    CGAffineTransformMakeRotation(CGFloat(M_PI))
    CGAffineTransform(rotationAngle: CGFloat(M_PI))
    

    动词和排名

    先让大家看一段代码

    myArray.enumerate()
    myArray.enumerated()
    
    myArray.reverse()
    myArray.reversed()
    

    各种Swift3的修改章程都增多了d,代表那些值正被重临。还会有正是在数组排序的意况下。swift 2.2 使用 sort()再次回到一个排序还的数组,而 sortInPlace()则完结内部排序。在斯维夫特 3.0中 sort()形成了sorted(),sortInPlace()变成了sort()。那也就代表那斯维夫特2.第22中学sort()会回到数组,而在Swift 3.0中央市直机关接内部排序。

    与 -- 操作符

    自增自减是源于 C 的操作符,功能是对变量直接实行 1或 -1的操作:

    var i = 0 
    i   
      i 
    i-- 
    --i
    

    只是,在大家要选择使用哪一类操作符进行演算的时候,事情就变得复杂起来。无论是自增依旧自减,都对应着二种写法:写在在变量以前,还是在变量之后。它们的平底完毕其实都以有重临值的函数,是还是不是利用再次来到值取决于对运算符的重载。
    那或者会吓跑初学者,所以苹果移除了该个性——替代它的是复合加法运算( =)与减法运算(-=):

    var i = 0
    i  = 1
    i -= 1
    

    理所必然,你也足以使用普通的加法运算( )与减法运算(-),固然复合式运算符写起来要短一点:

    i = i   1
    i = i - 1
    

    C 风格的 for 循环已成历史

    骨子里自增自减运算符用得最多的地点,仍旧在 for 循环部分。移除该运算符意味着 for 循环的表征也随即远去了,因为在 for-in 的社会风气中,循环调控语句与限定界定用不上该操作符。
    要是您有必然编制程序背景,那么输出 1 到 100 的数,你也许会这么写:

    for (i = 1; i <= 10; i  ) { 
    print(i)
    }
    

    在 Swift 3 中,已经不容许这种写法了,而相应写为(注意闭区间范围的写法):

    for i in 1...10 { 
    print(i)
    }
    

    要么,你也足以运用 for-each 加闭包的写法:

    (1...10).forEach { 
    print($0)
    }
    

    一、通透到底移除在 Swift 2.2 就早就弃用的特色

    移除函数参数的 var标识

    设若不必要在函数内部对参数举行修改的话,函数参数经常都定义为常量。然则,在好几情形下,定义成变量会更为方便。在 斯维夫特 2 中,你能够用 var关键字来将函数参数标志为变量。一旦参数用 var来标志,就能够生成一份变量的正片,如此便能在点子内部对变量举行改造了。
    下边是叁个求三个数的最大公约数的例子:

    func gcd(var a: Int, var b: Int) -> Int {  
        if (a == b) { return a }  
        repeat { 
            if (a > b) { a = a - b 
                } else { b = b - a } 
        } while (a != b) 
     return a
    }
    

    那一个算法的逻辑很轻便:假使四个数相等,则赶回在那之中贰个的值。不然,做大小相比,大的数减去小的数之后,将差值赋值给大的数,然后再将多个数作比较,结束它们也等于截至,最后回到个中叁个的值。正如你所见到的,通过将 a和 b标志为变量,才干在函数体里对四个数举行修改。
    Swift 3 不在允许开采者那样来将参数标志为变量了,因为开采者也许会在 var和 inout纠结不已。所以新型的 斯维夫特 版本中,就干脆移除了函数参数标志 var 的特色。
    那样,想要用 斯威夫特 3 来写上边的 gcd函数,将在另辟蹊径了。你须要在函数内部创制有时变量来存款和储蓄参数:

    func gcd(a: Int, b: Int) -> Int {  
          if (a == b) { return a }  
          var c = a 
          var d = b 
          repeat { 
              if (c > d) { 
                  c = c - d 
            } else { 
                  d = d - c 
            } 
        } while (c != d)  
    return c
    }
    

    那个特点在我们选取 Xcode 7.3 的时候就已经有报警提示,在 斯维夫特 3 中已将其根本移出。

    函数参数标签的一致性

    函数的参数列表底层达成其实是元组,所以只要元组结议和函数参数列表同样,你能够平昔用元组来替代参数列表。就拿刚才的 gcd()
    函数来说,你能够这么调用:

    gcd(8, b: 12)
    

    您也足以如此调用:

    let number = (8, b: 12)gcd(number)
    

    正如您所见到的,在 Swift 2中,第贰个参数无需带标签,而从第三个参数先河,就供给求带标签了。
    那个语法对初学者的话也许会招致疑忌,所以,要拓展联合标签设计。在 斯维夫特 3 中,函数的调用要像上边那样:

    gcd(a: 8, b: 12)
    

    固然是率先个参数,也不可能不带上标签。尽管不带,Xcode 8 会直接报错。
    你对那修改的首先个反应可能是:「小编哔!那笔者代码退换得多大啊!」是的,那简直是成吨的迫害。所以苹果又交给了一种不用给第三个参数带标签的减轻方案。在第一个参数前边加上二个下划线:

    func gcd(_ a: Int, b: Int) -> Int { ... }
    

    不过尔尔做,事情又就好像回到了原点——第三个参数不用带标签了。使用这种艺术,应该能自然水平上下滑 Swift 2 搬迁到 Swift 3 上的惨恻。

    1、弃用 与 -- 操作符

    Selector 不再允许利用 String

    让我们来创立一个开关,并给它加多三个点击事件(无需分界面援助,直接行使 playground 就行):

    // 1
    import UIKit
    import XCPlayground 
    // 2
    class Responder: NSObject {  
        func tap() { print("Button pressed") }
    }
    let responder = Responder()
    // 3
    let button = UIButton(type: .System)
    button.setTitle("Button", forState: .Normal)
    button.addTarget(responder, action: "tap", forControlEvents: .TouchUpInside)
    button.sizeToFit()
    button.center = CGPoint(x: 50, y: 25) 
    // 4
    let frame = CGRect(x: 0, y: 0, width: 100, height: 50)
    let view = UIView(frame: frame)
    view.addSubview(button)
    XCPlaygroundPage.currentPage.liveView = view
    

    让大家一步一步深入分析下方面的代码:
    导入 UIKit与 XCPlayground 框架——需求成立三个按键,并在 playground 的 assistant editor 中开始展览显示。
    注意:你要求在 Xcode 菜单栏上的 View -> Assistant Editor -> Show Assistant Editor 来开启 assistant editor。

    始建点击的接触事件,能在用户点击开关时,触发绑定的风云——那必要基类为 NSObject,因为 selector 仅对 Objective-C 的主意使得。

    表明按键,并布署相关属性。

    表明视图,给定合适的轻重缓急,将按键加多到视图上,最终突显在 playground 的 assistant editor 中。

    让大家来看下给按键增加事件的代码:

    button.addTarget(responder, action: "tap", forControlEvents: .TouchUpInside)
    

    此地按键的 selector 依旧写的字符串。假诺字符串拼写错了,那程序会在运作时因找不到相关方法而夭折。
    为了消除编写翻译时期的机密问题,Swift 3 将字符串 selector 的写法改为了 #selecor()。那将允许编写翻译器提前检检查办理法名的拼写难题,而不用等到运转时。

    button.addTarget(responder, action: #selector(Responder.tap), for: .touchUpInside)
    

    以上正是关于移除个性的全体内容。接下来,让大家来探视语言今世化的一对独到之处。

    千古大家得以行使 与 -- 操作符来促成自增自减,现已甩掉。

    不再是 String 的 key-path 写法

    其一特性和上多个很相像,不过那是用在键值编码(KVC)与键值旁观(KVO)上的:

    class Person: NSObject { 
      var name: String = ""  
      init(name: String) { 
          self.name = name 
        }
    }
    let me = Person(name: "Cosmin")
    me.valueForKeyPath("name")
    

    先是创造了 Person类,那是 KVC 的主要条件。然后用钦赐的构造器初步化两个me,最终通过 KVC 来修改 name。同样,假若 KVC 中的键拼写错误,那全体就白瞎了 。
    有幸的是,斯维夫特 3 中就不会再出现这么些情景了。字符串的 key-path 写法被沟通为了 #keyPath():

    class Person: NSObject { 
        var name: String = ""  
         init(name: String) { 
          self.name = name 
          }
    }
    let me = Person(name: "Cosmin")
    me.value(forKeyPath: #keyPath(Person.name))
    
    var i = 0
    i  
      i
    i--
    --i
    

    Foundation 去掉 NS前缀

    大家先来拜望有 NS前缀时的写法,上面是一个举世无双的 JSON 分析例子:

    let file = NSBundle.mainBundle().pathForResource("tutorials", ofType: "json")
    let url = NSURL(fileURLWithPath: file!)
    let data = NSData(contentsOfURL: url)
    let json = try! NSJSONSerialization.JSONObjectWithData(data!, options: [])
    print(json)
    

    以上代码应用了 Foundation 相关类来对文本中的 JSON 数据实行分析:NSBundle -> NSUEscortL -> NSData -> NSJSONSerialization。
    在 斯威夫特 3 中,将移除 NS前缀,所以,深入分析流程形成了:Bundle -> U景逸SUVL -> Data -> JSON塞里alization。

    let file = Bundle.main().pathForResource("tutorials", ofType: "json")
    let url = URL(fileURLWithPath: file!)
    let data = try! Data(contentsOf: url)
    let json = try! JSONSerialization.jsonObject(with: data)
    print(json)
    

    能够采纳复合加法运算( =)与减法运算(-=),只怕使用普通的加法运算( )与减法运算(-)达成均等的效应。

    M_PI还是 .pi

    下边是贰个已知半径求圆周长的例证:

    let r = 3.0
    let circumference = 2 * M_PI * r
    let area = M_PI * r * r
    

    在旧版本的 Swift 中,大家选择 M_PI 常量来表示 π。而在 Swift 3 中,π 整合为了 Float,Double 与 CGFloat 二种情势:

    Float.piDouble.piCGFloat.pi
    

    所以地方求圆周长的例子,在 斯维夫特 3 中应有写为:

    let r = 3.0
    let circumference = 2 * Double.pi * r
    let area = Double.pi * r * r
    

    依据项目估计,大家得以将品种前缀移除。更为轻便的本子如下:

    let r = 3.0
    let circumference = 2 * .pi * r
    let area = .pi * r * r
    

    2、撤除C语言风格的for循环

    GCD

    Grand Central Dispatch(GCD)多用于解决网络央浼时,阻塞主线程的 UI 刷新难题。那是用 C 写的,并且 API 对初学者也并不友善,以致想要成立个为主的异步线程也只能那样写:

    let queue = dispatch_queue_create("Swift 2.2", nil)
    dispatch_async(queue) { print("Swift 2.2 queue")}
    

    Swift 3 撤废了这种冗余的写法,而选择了越来越面向对象的办法:

    let queue = DispatchQueue(label: "Swift 3")
    queue.async { print("Swift 3 queue")}
    

    我们过去大概习于旧贯下边风格的 for 循环,未来也已吐弃。

    更 Swift 范的 Core Graphics

    Core Graphics 是三个非常强劲的绘图框架,然而和 GCD 同样,它还是是 C 风格的 API:

    let frame = CGRect(x: 0, y: 0, width: 100, height: 50) 
    class View: UIView {  
        override func drawRect(rect: CGRect) { 
            let context = UIGraphicsGetCurrentContext() 
            let blue = UIColor.blueColor().CGColor           
            CGContextSetFillColorWithColor(context, blue) 
            let red = UIColor.redColor().CGColor 
            CGContextSetStrokeColorWithColor(context, red)     
            CGContextSetLineWidth(context, 10) 
            CGContextAddRect(context, frame) 
            CGContextDrawPath(context, .FillStroke) 
        }
    }
    let aView = View(frame: frame)
    

    地方代码,首先创制了 view 的 frame,然后创造多个接续自 UIView的 View类,重写 drawRect()方法来重绘 view 的内容。
    在 斯威夫特 3 中,有不一样的完结方式——对现阶段画布上下文解包,之后的具备绘制操作就都基于解包对象了:

    let frame = CGRect(x: 0, y: 0, width: 100, height: 50) 
    class View: UIView {  
        override func draw(_ rect: CGRect) { 
          guard let context = UIGraphicsGetCurrentContext() else { return }        
          let blue = UIColor.blue().cgColor 
          context.setFillColor(blue) 
          let red = UIColor.red().cgColor 
          context.setStrokeColor(red) 
          context.setLineWidth(10) 
          context.addRect(frame) 
          context.drawPath(using: .fillStroke) 
        }
      }
    let aView = View(frame: frame)
    

    注意:在 view 调 drawRect()方法此前,上下文均为 nil,所以选取guard关键字来处理

    今昔能够行使 for-in 循环,可能选拔 for-each 加闭包的写法达成均等的功力。

    动词与名词的命名约定

    是时候介绍些土耳其共和国(The Republic of Turkey)语语法相关的更换了!Swift 3 将艺术分为了两大类:一类是重回两个老少咸宜的值的法子,就好像名词;一类是处理局地平地风波的,就如动词。
    来探视这么些输出 10 到 1 的事例:

    for i in (1...10).reverse() { print(i)}
    

    大家选用了 reverse()方法来反向数组。斯维夫特 3 中,改为用名词来做方法名——为它助长了 ed后缀:

    for i in (1...10).reversed() { print(i)}
    

    在元组中,最常见的输出数组内容的章程是:

    var array = [1, 5, 3, 2, 4]
    for (index, value) in array.enumerate() {
     print("(index   1) (value)")
    }
    

    Swift 3 中,同样对有关的 enumerate()方法名做出了名词性的退换——同样丰裕了 ed后缀:

    var array = [1, 5, 3, 2, 4]
    for (index, value) in array.enumerated() { 
    print("(index   1) (value)")
    }
    

    别的叁个例子是数组排序。上边是将数组升序排列的事例:

    var array = [1, 5, 3, 2, 4]
    let sortedArray = array.sort()
    print(sortedArray)
    

    Swift 3 上校 sort()方法修改为了 sorted():

    var array = [1, 5, 3, 2, 4]let sortedArray = array.sorted()print(sortedArray)
    

    再让大家来探问直接对数组进行排序,并非用中间量来选拔是怎么着的。在 斯威夫特2 中,你会像上边这样写:

    var array = [1, 5, 3, 2, 4]array.sortInPlace()print(array)
    

    大家选择了 sortInPlace()方法来对可变数组实行排序。斯维夫特 3 中,以为这种没有重回值,仅仅是管理排序的操作应该是动词行为。所以,应该选拔了多个很基本的动词来说述这种操作——将 sortInPlace()重命名称为了 sort():

    var array = [1, 5, 3, 2, 4]array.sort()
    print(array)
    
    //for-in循环
    for i in 1...10 {
        print(i)
    }
    //for-each循环
    (1...10).forEach {
        print($0)
    }
    

    更 Swift 范的 API

    斯维夫特 3 选择了更富有哲理性 API 设计艺术——移除不需要的单词。所以,假诺有个别词是剩下的,只怕是能依赖上下文臆度出来的,那就平昔移除:

    XCPlaygroundPage.currentPage
     改为 PlaygroundPage.current
    
    button.setTitle(forState)
     改为 button.setTitle(for)
    
    button.addTarget(action, forControlEvents)
     改为 button.addTarget(action, for)
    
    NSBundle.mainBundle()
     改为 Bundle.main()
    
    NSData(contentsOfURL)
     改为 URL(contentsOf)
    
    NSJSONSerialization.JSONObjectWithData()
     改为 JSONSerialization.jsonObject(with)
    
    UIColor.blueColor()
     改为 UIColor.blue()
    
    UIColor.redColor()
     改为 UIColor.red()
    

    3、移除函数参数的 var 标识

    枚举成员

    Swift 3 将枚举成员当做属性来看,所以选拔小写字母开始实际不是以前的大写字母:

    .System
     改为 .system
    
    .TouchUpInside
     改为 .touchUpInside
    
    .FillStroke
     改为 .fillStroke
    
    .CGColor
     改为 .cgColor
    

    在 Swift 函数中,参数暗中认可是常量。过去得以在参数前加关键字 var 将其定义为变量,那样函数内部就足以对该参数进行修改(外界的参数任然不会被涂改)。

    @discardableResult

    在 Swift 3 中,若无收到某艺术的重回值,Xcode 会报出警告。如下:

    图片 2

    在地点的代码中,printMessage方法再次来到了一条音信给调用者。可是,这一个重回值并从未被收取。那只怕会存在潜在难点,所以编写翻译器在 斯威夫特 3 中会给你报告警察方告。
    这种状态下,并不一定要收到再次回到值来清除警告。还足以经过给艺术表明@discardableResult来达到解除指标:

    override func viewDidLoad() { 
       super.viewDidLoad()  
        printMessage(message: "Hello Swift 3!")
    } 
    @discardableResult func printMessage(message: String) -> String { 
        let outputMessage = "Output : (message)" 
        print(outputMessage)  
        return outputMessage
    }
    
    var age = 22
    add(age)
    func add(var age:Int) {
        age  = 1
    }
    

    方今这种做法早已被撇下,Swift 3 不再允许开垦者那样来将参数标识为变量了。

    4、全体函数参数都必须带上标签

    过去假设叁个函数有五个参数,调用的时候第一个参数不须要带标签,而从第三个参数开头,供给求带标签。

    let number = additive(8, b: 12)
    func additive(a:Int, b:Int) -> Int{
        return a   b
    }
    

    现在为了有限协助函数参数标签的一致性,全体参数都不可能不带上标签。

    let number = additive(a: 8, b: 12)
    func additive(a:Int, b:Int) -> Int{
        return a   b
    }
    

    其一转变或者会促成大家的类型代码要举行极大的改动,终归涉及的地点重重。所以苹果又提交了一种不用给第多少个参数带标签的缓和方案。即在第三个参数前面加上多个下划线。
    (但是这一个只是便利大家代码从 Swift2 迁移到 Swift3 的一个折中方案,能够的话仍然提出将富有的参数都带上标签。)

    let number = additive(8, b: 12)
    func additive(_ a:Int, b:Int) -> Int{
        return a   b
    }
    

    5、函数表明和函数调用都需求括号来总结参数

    我们得以动用函数类型作为参数 ,对于二个参数是函数、重回值也是函数的函数。原本我们恐怕会如此写:

    func g(a: Int -> Int) -> Int->Int { ... }
    

    当如此不行难以阅读,极不好看出参数在哪个地方甘休,重返值又从哪个地方开端。在 Swift3 中成为那样定义这一个函数:

    func g(a:(Int) -> Int) -> (Int) -> Int { ... }
    

    6、Selector 不再允许行使 String

    假若大家给按键增添二个点击事件响应,点击后进行 tapped 函数。在此之前能够这么写:

    button.addTarget(responder, action: "tapped", forControlEvents: .TouchUpInside)
    

    但出于按键的 selector 写的是字符串。假若字符串拼写错了,那程序会在运作时因找不到有关方法而夭亡。所以 Swift 3 将这种写法撤除,改成 #selecor()。那样就将允许编写翻译器提前检查办法名的拼写难点,而不用再等到运维时才意识标题。

    button.addTarget(self, action:#selector(tapped), for:.touchUpInside)
    

    二、斯维夫特 3 的新特征

    1、内联类别函数sequence

    斯维夫特 3 新增加了七个全局函数:sequence(first: next:) 和 sequence(state: next:)。使用它们能够回去二个无比系列。上边是四个简便的施用样例,更详细的牵线能够本人的另一篇小说:斯威夫特

    • 内联体系函数sequence介绍(附样例)

      // 从某二个树节点平昔进步遍历到根节点 for node in sequence(first: leaf, next: { $0.parent }) {     // node is leaf, then leaf.parent, then leaf.parent.parent, etc. }// 遍历出全数的2的n次方数(不挂念溢出) for value in sequence(first: 1, next: { $0 * 2 }) {     // value is 1, then 2, then 4, then 8, etc. }

    2、 key-path不再只好采取String

    以此是用在键值编码(KVC)与键值观察(KVO)上的,具体 KVC、KVO 相关内容可以参照作者原先写的那篇小说:斯维夫特 - 反射(Reflection)的介绍与使用样例(附KVC介绍)
    小编们如故得以延续使用 String 类型的 key-Path:

    //用户类
    class User: NSObject{
        var name:String = ""  //姓名
        var age:Int = 0  //年龄
    }
    //创建一个User实例对象
    let user1 = User()
    user1.name = "hangge"
    user1.age = 100
    //使用KVC取值
    let name = user1.value(forKey: "name")
    print(name)
    //使用KVC赋值
    user1.setValue("hangge.com", forKey: "name")
    

    但提议使用激增的 #keyPath() 写法,那样能够制止大家因为拼写错误而吸引难题。

    //使用KVC取值
    let name = user1.value(forKeyPath: #keyPath(User.name))
    print(name)
    //使用KVC赋值
    user1.setValue("hangge.com", forKeyPath: #keyPath(User.name))
    

    3、Foundation 去掉 NS 前缀

    Swift3新特征汇总,的某些有别于。譬喻说过去我们选拔 Foundation 相关类来对文件中的 JSON 数据开始展览辨析,这么写:

    let file = NSBundle.mainBundle().pathForResource("tutorials", ofType: "json")
    let url = NSURL(fileURLWithPath: file!)
    let data = NSData(contentsOfURL: url)
    let json = try! NSJSONSerialization.JSONObjectWithData(data!, options: [])
    print(json)
    

    在 Swift 3 中,将移除 NS 前缀,就改为了:

    let file = Bundle.main.path(forResource: "tutorials", ofType: "json")
    let url = URL(fileURLWithPath: file!)
    let data = try! Data(contentsOf: url)
    let json = try! JSONSerialization.jsonObject(with: data) 
    print(json)
    

    4、除了M_PI 还有 .pi

    Swift3新特征汇总,的某些有别于。在过去,大家选取 M_PI 常量来代表 π。所以遵照半径求周长代码如下:

    let r = 3.0
    let circumference = 2 * M_PI * r
    

    在 斯维夫特 3 中,π 提供了 Float,Double 与 CGFloat 三种样式(Float.pi、Double.pi、CGFloat.pi),所以求周长仍是能够如此写:

    let r =  3.0
    let circumference = 2 * Double.pi * r
    //我们还可以将前缀省略,让其通过类型自动推断
    let r = 3.0
    let circumference = 2 * .pi * r
    

    5、简化GCD的写法

    至于 GCD,小编原本写过一篇相关小说:斯威夫特 - 八线程实现形式(3) - Grand Central Dispatch(GCD)
    过去写法选择 C 语言的作风,初学者只怕会十分小适应。举例创制三个简易的异步线程:

    let queue = dispatch_queue_create("Swift 2.2", nil)
    dispatch_async(queue) {
        print("Swift 2.2 queue")
    }
    

    Swift 3 撤销了这种冗余的写法,而接纳了越发面向对象的法门:

    let queue = DispatchQueue(label: "Swift 3")
    queue.async {
        print("Swift 3 queue")
    }
    

    6、Core Graphics的写法也愈发面向对象化

    Core Graphics 是二个分外壮大的绘图框架,然而和 GCD 同样,它原来的 API 也是 C 语言风格的。
    比方大家要开创一个 view,其里面背景使用 Core Graphics 举办绘图(玫瑰栗褐边框,杏黄背景)。过去大家这么写:

    class View: UIView {
        override func drawRect(rect: CGRect) {
            let context = UIGraphicsGetCurrentContext()
            let blue = UIColor.blueColor().CGColor
            CGContextSetFillColorWithColor(context, blue)
            let red = UIColor.redColor().CGColor
            CGContextSetStrokeColorWithColor(context, red)
            CGContextSetLineWidth(context, 10)
            CGContextAddRect(context, frame)
            CGContextDrawPath(context, .FillStroke)
        }
    }let frame = CGRect(x: 0, y: 0, width: 100, height: 50)
    let aView = View(frame: frame)
    

    在 Swift 3 中改正了写法,只要对现阶段画布上下文解包,之后的拥有绘制操作就都基于解包对象。

    class View: UIView {
        override func draw(_ rect: CGRect) {
            guard let context = UIGraphicsGetCurrentContext() else {
                return
            }
            let blue = UIColor.blue.cgColor
            context.setFillColor(blue)
            let red = UIColor.red.cgColor
            context.setStrokeColor(red)
            context.setLineWidth(10)
            context.addRect(frame)
            context.drawPath(using: .fillStroke)
        }
    }let frame = CGRect(x: 0, y: 0, width: 100, height: 50)
    let aView = View(frame: frame)
    

    7、新添的访谈调控关键字:fileprivate、open

    在 Swift 3 中在原本的 3 个访谈调整关键字 private、public、internal 外。又增加了2个新重视字 fileprivate、open。它们能够作为是对原先 private 和 public 的更是划分。具体选择情势和介绍能够看自个儿写的另一篇小说:Swift

    • Swift3新添的三个访谈调控关键字介绍(fileprivate、open)

    三、一些语法的修改

    1、数组排序:sort()与sorted()

    过去数组排序的七个格局:sortInPlace() 和 sort(),未来个别更名成 sort() 和 sorted()
    sort() 是直接对目的数组进行排序。sorted() 是回去一个排序后的数组,原数组不改变。

    var array1 = [1, 5, 3, 2, 4]
    array1.sort()
    print(array1)  //[1, 2, 3, 4, 5]
    var array2 = [1, 5, 3, 2, 4]
    let sortedArray = array2.sorted()
    print(array2)  //[1, 5, 3, 2, 4]
    print(sortedArray)  //[1, 2, 3, 4, 5]
    

    2、reversed()与enumerated()

    千古 reverse() 方法完结数组反转,enumerate() 方法实现遍历。现那三个法子都抬高 ed 后缀(reversed、enumerated)

    for i in (1...10).reversed() {
        print(i)
    }
    let array = [1, 5, 3, 2, 4]
    for (index, value) in array.enumerated() {
        print("(index   1) (value)")
    }
    

    3、CGRect、CGPoint、CGSize

    过去的 CGRectMake、CGPointMake、CGSizeMake 已废弃。现改用 CGRect、CGPoint、CGSize 代替。

    //Swift 2
    let frame = CGRectMake(0, 0, 20, 20)
    let point = CGPointMake(0, 0)
    let size = CGSizeMake(20, 20)
    //Swift 3
    let frame = CGRect(x: 0, y: 0, width: 20, height: 20)
    let point = CGPoint(x: 0, y: 0)
    let size = CGSize(width: 20, height: 20)
    

    4、移除了API中剩下的单词

    • XCPlaygroundPage.currentPage 改为 PlaygroundPage.current
    • button.setTitle(forState) 改为 button.setTitle(for)
    • button.addTarget(action, forControlEvents) 改为 button.addTarget(action, for)
    • arr.minElement() 改为 arr.min()
    • arr.maxElement() 改为 arr.max()
    • attributedString.appendAttributedString(anotherString) 改为 attributedString.append(anotherString)
    • names.insert("Jane", atIndex: 0) 改为 names.insert("Jane", at: 0)
    • NSBundle.mainBundle() 改为 Bundle.main
    • UIDevice.currentDevice() 改为 UIDevice.current
    • NSData(contentsOfURL) 改为 Data(contentsOf)
    • NSJSONSerialization.JSONObjectWithData() 改为 JSONSerialization.jsonObject(with)
    • UIColor.blueColor() 改为 UIColor.blue

    5、枚举成员成为小写字母开首

    斯威夫特 3 将枚举成员当做属性来看,所以现在利用小写字母初步实际不是在此在此之前的大写字母。

    .system //过去是:.System
    .touchUpInside //过去是:.TouchUpInside
    .fillStroke //过去是:.FillStroke
    .cgColor //过去是:.CGColor
    

    6、@discardableResult

    在 斯维夫特 3 中,假使贰个格局有再次来到值。而调用的时候未有收受该情势的重返值,Xcode 会报出警告,告诉你这可能会设有潜在难点。

    图片 3

    除却能够通过接收再次来到值化解警告。还足以经过给艺术表明 @discardableResult 来达到解除指标。

    .system //过去是:.System
    .touchUpInside //过去是:.TouchUpInside
    .fillStroke //过去是:.FillStroke
    .cgColor //过去是:.CGColor
    
    import UIKit
    class ViewController: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad()
            printMessage(message: "Hello Swift 3!")
        }
        @discardableResult
        func printMessage(message: String) -> String {
            let outputMessage = "Output : (message)"
            return outputMessage
        }
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
        }
    }
    

    原稿出自:航歌网

    本文由新葡亰496net发布于奥门新萄京娱乐场,转载请注明出处:Swift3新特征汇总,的某些有别于

    关键词: