Xcode9和Swift4新特性

XCode9新特性
1. 支持远程调试
2. Xcode绑定Github账号
3. 支持Swift类重命名
4. Swift低版本兼容
5. Main Thread Checker
6. 模拟器支持多开
7. 标示功能
8. 协议自动补全
9. 代码段自动抽出函数
10. 自定义颜色名称
11. Debug View Hierarchy可以显示ViewController了
12.支持Markdown,可以在xcode中查阅、编辑markdown文件

Swift4更新
1. Extension可以访问private的属性
2. 类型和协议的组合类型
3. 新的Key Paths 语法
4. 下标支持泛型
5. 字符串
5.1 可以直接获取字符串长度了
5.2 字符串获取子串语法糖… One-sided Slicing
5.3 String增加了Collection的一些特性
5.4 多行字符串
6. 序列化的简化
7. Dictionary and Set增强
7.1 通过Sequence初始化
7.2 字典过滤后类型不变
7.3 新增mapValues函数
7.4 字典支持默认值
8. MutableCollection新增swapAt(::) 用来交换两个位置的值

上篇文章我们介绍了iOS11适配iPhoneX总结,这次分享下Xcode9和Swift4新特性。欢迎关注微信公众号:乐Coding获得最新文章。

XCode9新特性

新特性每次都是:更快、更高、更强

1. 支持远程调试

从来没有接过的iOS设备要先插入一次,然后在设备窗口选中 Connect via Network选项,之后就可以断开设备进行网络调试。

如果是已经插入过的手机,插入Mac后选中Xcode的 Window -> Devices and Simulators -> Devices -> 勾选Connect via network

这里有一个前提:iPhone必须升级到iOS11,电脑和iPhone在同一个局域网下。

1005.png

勾选过一次,以后调试就不用数据线了,爽不爽!手机右边有个网络小星球说明是远程设备。

10051.png

2. Xcode绑定Github账号

点击右上角Xcode -> Preferences ->

1006.png
1007.png

3. 支持Swift类重命名

原来的版本一直不支持Swift语言的重命名操作,终于啊终于...此时应该高歌一曲

等了好久终于等到今天
梦了好久终于 把梦实现
前途漫漫任我闯幸亏还有你在身旁
盼了好久终于 盼到今天
梦了好久终于 把梦实现

4. Swift低版本兼容

原来每次升级Xcode都要convert Swift进行升级,现在Xcode9兼容Swift3.2

1008.png

5. Main Thread Checker

Xcode9以前不会自动检测是否在非主线程更新UI,这样会有安全隐患。现在Xcode9自动附带了Main Thread Checker功能。一旦在非主线程操作UI就会在命令行警告:类似如下:

Main Thread Checker: UI API called on a background thread: -[UIView subviews]
PID: 28353, TID: 267810, Thread name: (none), Queue name: com.apple.root.user-initiated-qos, QoS: 25

现在读秒项目中第三方的小米推送和Bugtags、诸葛IO都有这个问题,需要更新到最新版。小米推送一直没更新,我上周给他们发邮件反馈周四才更新。

6. 模拟器支持多开

可以同时打开多个型号模拟器

7. 标示功能

  • 范围标示

    将游标移到 { } 、( ) 或是 class、func、if、for 等关键字时,按住 command 键,Xcode 将聪明地标示对应的 class、function、if、for 区块。

10087.png
  • 提示功能

    跟刚刚一样,将游标移到关键字上,按住 command 键,然后点击,即可出现贴心的提示选单。

    比方如图所示,游标停在 if 上,按住 command 键点击后提示选单出现 Add “else” Statement 和 Add “else if” Statement,Extract Method 等选项。选择 add “else” Statement 后,自动完成 else { } 的输入。

8. 协议自动补全

Swift的protocol中必须实现的函数当没有实现时会报错,有时我们需要点击协议定义的地方查看必须实现那些函数。现在Xcode9支持自动补全必须实现的函数

例如UIViewController遵循UITableViewDataSource协议,当未实现函数时会有红色错误提示,点击Fix就会自动补全。

补全前
补全后

9. 代码段自动抽出函数

选中一段代码,右键选择Refactor -> Extract Method 就会把选中的代码段单独抽出一个函数。这个功能在代码重构中很有用。

1011.png

10. 自定义颜色名称

可以在 Assets.xcasset 里添加颜色,取个名称,然后在代码或者 Storyboard 中引用这个颜色了。

  • 在 Assets.xcassets 页面,右键选择New Color Set
1012.png
  • 然后设置颜色和名字
1013.png
  • 在xib或者sb中使用的时候可以直接在Named Colors中选择
1014.png
  • 代码中使用,现在代码中只能iOS11以上可以用

    if #available(iOS 11.0, *) {
        self.view.backgroundColor = UIColor(named:"MainBlue")
    }
    

11. Debug View Hierarchy可以显示ViewController了

Debug View Hierarchy是一个很好的页面调试工具,方便研究页面上的控件,原来是无法看到当前Controller的,现在Xcode9中可以看到了。

1015.png

12.支持Markdown,可以在xcode中查阅、编辑markdown文件

Swift4更新

1. Extension可以访问private的属性

在Swift3中类、结构体和枚举的扩展中不能访问private属性。

下面这种写法会报错:'strName' is inaccessible due to 'private' protection level

class ViewController: UIViewController {
    private var strName:String = "test"
}
extension ViewController{
    func testFunc()  {
        print("\(self.strName)") //'strName' is inaccessible due to 'private' protection level
    }
}

必须把private换成fileprivate才可以,但是权限又被扩大了。到了Swift4中extension也可以访问private中的属性了。

2. 类型和协议的组合类型

//2.1 定义类
class Person {
     var name:String?
}
class Student: Person {
    var sId:Int = 0
}
class Teacher: Person {
}
//2.2 协议
protocol Runnable {
    func run()
}
protocol Singing {
    func sing()
}
//拓展子类
extension Student :Runnable, Singing{
    func run() {
        print("\(self.name ?? "")会跑步")
    }
    func sing() {
         print("\(self.name ?? "")会唱歌")
    }
}
extension Teacher :Runnable{
    func run() {
        print("\(self.name ?? "")会跑步")
    }
}

extension ViewController {
    //man既能唱又能跑,还有名字
    func test2(human:Person&Singing&Runnable)  {
        if (human.name?.count ?? 0) > 0 {
            human.run()
            human.sing()
        }
    }
}

如果在Swift3中只能像下面这样写

func test2(man:Person)  {
    if (man.name?.characters.count ?? 0) > 0 {
        if let mm = man as? Runnable{
            mm.run()
        }
        if let mm = man as? Singing{
            mm.sing()
        }
    }
}

3. 新的Key Paths 语法

Swift4可以使用\+点语法的形式创建KeyPath

let path:KeyPath = \Apple.color

例子:

//MARK: 3.0 新的Key Path语法
class Apple {
    var color:UIColor
    init(color:UIColor) {
        self.color = color
    }
}
extension ViewController {
    func test3(){
        let apple = Apple(color: UIColor.red)
        let c = apple[keyPath:\Apple.color]
        print("\(c)")
    }
}

Swift4的KeyPath具有以下优势:

  • 可以再 class、struct上使用
  • 定义类型时无需加上 @objcMembers、dynamic 等关键字,使用更简洁
  • 性能更好
  • 类型安全和类型推断,例如 apple.valueForKeyPath(color) 返回的类型是 Any,apple[keyPath: \Apple.color] 直接返回 UIColor 类型
  • 可以在所有值类型上使用

4. 下标支持泛型

在Swift4之前,下标属性只能返回Any类型,现在可以添加泛型约束

struct School<Key:Hashable , Value> {
    var studens:[Key: Value]
    init(studens:[Key: Value]) {
        self.studens = studens
    }
    subscript<Value>(key: Key) -> Value? {
        return studens[key] as? Value
    }
}
extension ViewController {
    func test4(){
        let tfboys = School(studens: ["001":"王俊凯","002":"易烊千玺","003":"王源"])
        let name:String? = tfboys["001"]
        print("\(name ?? "")") //王俊凯
    }
}

5. 字符串

5.1 可以直接获取字符串长度了

Swift3中想要获取字符串的长度必须: str.characters.count ,现在可以str.count直接获得了。

Swift 3 中的 String 需要通过 characters 去调用的一些属性方法,在 Swift 4 中可以通过 String 对象本身直接调用。

5.2 字符串获取子串语法糖 One-sided Slicing

Swift3中获取子串

let values = "欢迎关注微信公众号:乐Coding"
let startIndex = values.index(values.startIndex, offsetBy: 3)
let subvalues = values[startIndex..<values.endIndex]

Swift4中可以使用...语法

extension ViewController{
    func test5() {
        let str = "欢迎关注微信公众号:乐Coding"
        let start = str.index(str.startIndex, offsetBy: 2)
        let subStr = str[start...]
        let subStr2 = str[...start]
        print("\(subStr)  : \(subStr2)") //关注微信公众号:乐Coding  : 欢迎关
    }
}

5.3 String增加了Collection的一些特性

在Swift4中字符串做了一些Collection类似功能函数的扩展(并不是实现Collection协议,而是使用起来更像Collection,更友好)。

func test6()  {
      //1.0 字符串翻转
      let str = "Backwards"
      let str2 = str.reversed() //ReversedCollection<String>
      let reversedWord = String(str2)
      print(reversedWord) //sdrawkcaB
      //2. 0 遍历字符串
      for char in str {
          print(char, terminator: "") //Backwards
      }
      //3.0 Map
      print("\n---------- Map --------")
      _ = str.map {
          print($0.description+"...")
      }
      /* 打印
       B...
       a...
       c...
       k...
       w...
       a...
       r...
       d...
       s...
       */
      //4.0 Filter
      print("\n---------- Filter --------")
      let filtered = str.filter {
          $0 == "c"
      }
      print("\(filtered)") //c
      //5.0 Reduce
      let letters = "abracadabra"
      let letterCount = letters.reduce(into: [:]) { counts, letter in
            counts[letter, default: 0] += 1
       }
      print("\(letterCount)") //["b": 2, "a": 5, "r": 2, "d": 1, "c": 1]

  }

5.4 多行字符串

swift3中写多行字符串只能在字符串中添加\n,易读性不好。Swift4中新增加了多行字符串语法""",注意"""要单独占一行。

func test7(){
    let mutableLineStr =
    """
    小明:
        你妈叫你回家吃饭。
                    小红。
    """
    print(mutableLineStr)
}

打印结果:

1016.png

6. 序列化的简化

原来对象序列化,需要对象遵守NSCoding协议并实现下面三个方法,比较麻烦。

- (id)initWithCoder:(NSCoder *)coder;
- (void)encodeWithCoder:(NSCoder *)coder;
- (id)copyWithZone:(NSZone *)zone;

Swift4中只需要对象实现Codable协议。然后选择把对象转成Json(JSONEncoder)还是Plist(PropertyListEncoder)存储。

struct Animal:Codable {
    var name: String
    var age: Int
}

extension ViewController {
    func test8(){
        let cat = Animal(name: "wildcat", age: 2)
        //编码,存储
        if let encoded = try? JSONEncoder().encode(cat) {
            UserDefaults.standard.set(encoded, forKey: "MyCat")
            UserDefaults.standard.synchronize()
        }
        //获取,解码
        let decode = UserDefaults.standard.object(forKey: "MyCat") as? Data
        if let cat2 = try? JSONDecoder().decode(Animal.self, from: decode!){
            print("\(cat.name)") //wildcat
        }
    }
}

7. Dictionary and Set增强

7.1 通过Sequence初始化

字典通过Sequence创建的函数声明:

public init<S>(grouping values: S, by keyForValue: (S.Element) throws -> Key) rethrows where Value == [S.Element], S : Sequence

下面以数组转字典为例,字典的key是元素在数组中下标

let students = ["Kofi", "Abena", "Efua", "Kweku", "Akosua"]
let dic  = Dictionary(grouping: students) { (element) -> Int in
    return students.index(of: element) ?? 0
}
print("dic: \(dic)")
//dic: [4: ["Akosua"], 2: ["Efua"], 0: ["Kofi"], 1: ["Abena"], 3: ["Kweku"]]

7.2 字典过滤后类型不变

在Swift3中Dictionary调用filter后会返回一个数组,但我们肯定希望还是返回一个过滤后的Dictionary,在Swift4中按照我们希望的做了修改。

let cities = ["Shanghai": 24_256_800, "Karachi": 23_500_000, "Beijing": 21_516_000, "Seoul": 9_995_000];
let massiveCities = cities.filter { $0.value > 10_000_000 }
print("massiveCities: \(massiveCities)")
//massiveCities: ["Shanghai": 24256800, "Karachi": 23500000, "Beijing": 21516000]

//在Swift3中massiveCities返回的是一个数组,要访问massiveCities中的元素必须massiveCities[0].value。Swift4中变成我们期望的返回一个字典,可以massiveCities["Shanghai"]直接取

7.3 新增mapValues函数

先看下面例子:

let populations = cities.map { $0.value * 2 }
print("\(populations)")
//[48513600, 47000000, 43032000, 19990000]

我们原本希望populations返回的还是一个字典,只是值变成2倍,可是map在Swift4中并没有这么改,而是添加了一个mapValues()函数

let roundedCities = cities.mapValues { "\($0 / 1_000_000) million people" }
print("\(roundedCities)")
//["Shanghai": "24 million people", "Karachi": "23 million people", "Beijing": "21 million people", "Seoul": "9 million people"]

7.4 字典支持默认值

下面的let name =person["name", default: "Anonymous"]默认值语法,类似于let name = person["name"] ?? "Anonymous"

let person = ["name": "Taylor", "city": "Nashville"]
let name = person["name", default: "Anonymous"] //等价于 let name = person["name"] ?? "Anonymous"
print("\(name)") // Taylor
let create = person["create", default: "1984-01-01"]
print("\(create)") // 1984-01-01

还可以看一个统计数组中元素出现次数的例子:

let favoriteTVShows = ["Red Dwarf", "Blackadder", "Fawlty Towers", "Red Dwarf"]
var favoriteCounts = [String: Int]()
for show in favoriteTVShows {
    favoriteCounts[show, default: 0] += 1
}
print("favoriteCounts: \(favoriteCounts)")

8. MutableCollection新增swapAt(::) 用来交换两个位置的值

func test10() {
  var array = ["王俊凯","易烊千玺","王源"]
  array.swapAt(0, 1)
  print("\(array)")
  //["易烊千玺", "王俊凯", "王源"]
}

觉得不错请点击下方【喜欢】,为了微博认证也是拼了!还差1660个🤣


更多iOS、Swift、iOS逆向最新文章请关注微信公众账号:乐Coding,或者微信扫描下方二维码关注

lecoding

icon.jpg

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容

  • 因为要结局swift3.0中引用snapKit的问题,看到一篇介绍Xcode8,swift3变化的文章,觉得很详细...
    uniapp阅读 4,284评论 0 12
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,596评论 4 59
  • 命运的齿轮不停旋转 完美地画了一个圈 终点便是曾经的起点 骑士死于剑下 老马失足河边 延续了千年的愁思还没有剪断 ...
    弗念拂念阅读 188评论 0 0
  • 关了灯 开了门 樱花下路灯洒进如月 听琴音 扬了心 冬来几度寒雨 一地樱叶 扶慰一片春心
    得一生二阅读 150评论 2 2
  • 市面蛋糕店一般以轻芝士居多,国人口感独爱,重芝士则是老外的心头好,于是,打算今儿做一个6寸品尝下老外的口中的味道,...
    皓妈童书分享会阅读 332评论 6 7