Swift4.2新特性 & XCode 10更新


swift语法更新

SE-0079 允许self在闭包中使用可选绑定

// swift3
guard let `self` = self else {return}

// swift4.2
guard let self = self else {return}

使用上面代码分别在swift3、swift4.2的闭包中将弱引用的self转为强引用。但是Apple的Chris Lattner表示swift3的写法是“一个编译器错误”。

SE-0197添加removeAll(where:)方法到标准库,用于删除集合中满足条件的元素

//swift 3
var nums = [1,2,3,4,5]
// 删除奇数
nums = nums.filter { !isOdd($0) }

//swift 4.2
nums.removeAll(where: isOdd)

filter方法完成此操作存在性能问题 1.重新分配了内存,2.需完整拷贝原数组

SE-0199添加.toggle()方法到BOOL值,让原值反转

//swift 3
myVar.prop1.prop2.enabled = !myVar.prop1.prop2.enabled

//swift 4.2
myVar.prop1.prop2.enabled.toggle()

SE-0202随机数生成API

// 生成随机数
Int.random(in: 1...1000)
UInt8.random(in: .min ... .max)
Double.random(in: 0..<1)

// 随机从数组中取值
let emotions = "😀😂😊😍🤪😎😩😭😡"
let randomEmotion = emotions.randomElement()! //可能是其中一个

// 数组乱序
let numbers = 1...10
let shuffled = numbers.shuffled()//1-10的乱序数组

SE-0204添加last(where:)lastIndex(where:)获取集合中最后满足条件的元素和位置

// swift 3
let a = [20, 30, 10, 40, 20, 30, 10, 40, 20]
a.first(where: { $0 > 25 })         // 30
a.index(where: { $0 > 25 })         // 1
a.index(of: 10)                     // 2
// 需要获取最后的需要将集合倒序
(a.reversed().index(where: { $0 > 25 })?.base).map({ a.index(before: $0) })
// swift 4.2
a.last(where: { $0 > 25 })          // 40
a.lastIndex(where: { $0 > 25 })     // 7
a.lastIndex(of: 10)                 // 6

SE-0206Hashable重新设计

// swift 3
extension Point: Equatable{
    func ==(lhs: Testhash, rhs: Testhash) -> Bool {
        return lhs.hashValue == rhs.hashValue
    }
}
extension Point: Equatable {
    var hashValue: Int {
        get {
            return self.x + self.y * self.x
        }
    }
}

// swift 4.2
extension Point: Equatable {
    static func ==(lhs: Point, rhs: Point) -> Bool {
        // Ignore distanceFromOrigin for determining equality
        return lhs.x == rhs.x && lhs.y == rhs.y
    }
}
extension Point: Hashable {
    func hash(into hasher: inout Hasher) {
        // Ignore distanceFromOrigin for hashing
        hasher.combine(x)
        hasher.combine(y)
    }
}

SE-0207集合新增.allSatisfy方法,判断是否所有元素都满足闭包内的条件

// swift 3
//判断所有数是否都是奇数
!nums.contains { !isOdd($0) }
//swift 4.2
nums.allSatisfy(isOdd)

SE-0143条件一致性,现在可以在扩展(extension)中合成协议一致性,而不仅仅是在类型定义上(扩展必须仍然位于与类型定义相同的文件中),并且允许自动合成Equatable, Hashable, Encodable, 和 Decodable.


func isEncodable(_ value: Any) -> Bool {
    return value is Encodable
}
let encodableArray = [1, 2, 3]

//Swift 4.1
isEncodable(encodableArray) // false

//Swift 4.2
isEncodable(encodableArray) // true
struct NonEncodable {}
let nonEncodableArray = [NonEncodable(), NonEncodable()]
isEncodable(nonEncodableArray)// false 在不满足条件一致性条件时,动态查验不成功。

enum Either<Left, Right> {
    case left(Left)
    case right(Right)
}

// 扩展后无需写具体实现,编译器自动合成
extension Either: Equatable where Left: Equatable, Right: Equatable {}
extension Either: Hashable where Left: Hashable, Right: Hashable {}

Either<Int, String>.left(42) == Either<Int, String>.left(42)

SE-0212新增编译器版本指令

// swift 3
#if swift(>=4.1) || (swift(>=3.3) && !swift(>=4.0))
// Code targeting the Swift 4.1 compiler and above.
#endif

#if swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0))
// Code targeting the Swift 4.2 compiler and above.
#endif

#if swift(>=5.0) || (swift(>=4.1.50) && !swift(>=4.2)) || (swift(>=3.5) && !swift(>=4.0))
// Code targeting the Swift 5.0 compiler and above.
#endif

//swift4
#if swift(>=4.1) || (swift(>=3.3) && !swift(>=4.0))
// Code targeting the Swift 4.1 compiler and above.
// 低版本编译器兼容代码.
#endif

#if compiler(>=4.2)
// Code targeting the Swift 4.2 compiler and above.
#endif

#if compiler(>=5.0)
// Code targeting the Swift 5.0 compiler and above.
#endif

SE-0210添加MemoryLayout<T>.offset(of:)方法,返回一个指针地址偏移后的T类型的值

// C语言
// Layout of one of our vertex entries
struct MyVertex {
  float position[4];
  float normal[4];
  uint16_t texcoord[2];
};

enum MyVertexAttribute { Position, Normal, TexCoord };

glVertexAttribPointer(Position, 4, GL_FLOAT, GL_FALSE,
                      sizeof(MyVertex), (void*)offsetof(MyVertex, position));
glVertexAttribPointer(Normal, 4, GL_FLOAT, GL_FALSE,
                      sizeof(MyVertex), (void*)offsetof(MyVertex, normal));
glVertexAttribPointer(TexCoord, 2, GL_UNSIGNED_BYTE, GL_TRUE,
                      sizeof(MyVertex), (void*)offsetof(MyVertex, texcoord));
                      
//swift 4.2 
struct Point {
  var x, y: Double
}

struct Size {
  var w, h: Double

  var area: Double { return w*h }
}

struct Rect {
  var origin: Point
  var size: Size
}

MemoryLayout<Rect>.offset(of: \.origin.x) // => 0
MemoryLayout<Rect>.offset(of: \.origin.y) // => 8
MemoryLayout<Rect>.offset(of: \.size.w) // => 16
MemoryLayout<Rect>.offset(of: \.size.h) // => 24
MemoryLayout<Rect>.offset(of: \.size.area) // => nil

SE-0205只读属性withUnsafePointer(to:_:)withUnsafeBytes(of:_:) 顶层方法扩展

SE-0196编译器指令#warning#error

// swift4.2
 #warning("TODO: missing implementation")//编译器警告
 #error("This playground requires UIKit or AppKit")//编译失败报错

SE-0195动态成员查找,通过@dynamicMemberLookup声明属性 ,以获取 Python等语言的支持

// Python
class Dog:
   def __init__(self, name):
       self.name = name
       self.tricks = []    # creates a new empty list for each dog
   def add_trick(self, trick):
       self.tricks.append(trick)
       return self
----------------------------------------       
 //swift 4.2
 // import DogModule
 // import DogModule.Dog as Dog    // an alternate
 let Dog = Python.import("DogModule.Dog")
 let dog = Dog("Brianna")
 dog.add_trick("Roll over")
 let cuteDog = Dog("Kaylee").add_trick("snore")

SE-0194遍历普通枚举值

enum Terrain: CaseIterable {
    case water
    case forest
    case desert
    case road
}

Terrain.allCases
Terrain.allCases.count

使用CaseIterable后,枚举可以通过.allCases获取所有枚举值的数组

SE-0193模块间调用, 用@inlinable and @usableFromInline声明公共接口

// Inside CollectionAlgorithms module:
extension Sequence where Element: Equatable {
    /// Returns `true` iff all elements in the sequence are equal.
    @inlinable
    public func allEqual() -> Bool {
        var iterator = makeIterator()
        guard let first = iterator.next() else {
            return true
        }
        while let next = iterator.next() {
            if first != next {
                return false
            }
        }
        return true
    }
}

[1,1,1,1,1].allEqual()
Array(repeating: 42, count: 1000).allEqual()
[1,1,2,1,1].allEqual()

SE-0054废除隐式可选类型

let x: Int! = 5   //x:Int!
let y = x         //y:Int?
let z = x + 0     //z:Int

X在使用时被强制解包为Int类型,声明的类型表示可选类型,并且告知编译器可以强制解包[Int!]<T!>等类型将不再可用,类似的自动类型推导也将提示修改为指定类型

XCode 10更新


  1. 多行编辑:control + shift +鼠标单击

多行编辑在Mac OS10.14中可以在众多编辑器中使用如Sublime Text3中可以用command+鼠标单击 点击多行编辑(支持多行分别复制粘贴)

linesedit.gif

  1. 为快速查看弹出窗口添加了导出选项,用于数据类型,例如NSData


    屏幕快照 2018-09-19 上午11.04.52.png
  1. 现在,新创建的schemes默认由Xcode项目的所有用户共享。要创建个人方案,请取消选中Manage Schemes表中的Shared复选框

  2. 打开Library时按住Option键将使其在手动关闭之前保持可见,而不是在每次使用后自动关闭。(使用command+shift+M/L打开媒体库或UI组件库,拖去UI组件时按住Option壳使弹出视图不消失)

    屏幕快照 2018-09-19 上午11.24.25.png

  3. xcode的10增加了对C ++ 17个头部的支持<any>,<optional>和<variant>。(39271859)

  4. 命名颜色现在可以象征性地引用系统颜色。(39196638)

  5. libstdc ++已在xcode10弃用,C ++项目现在必须迁移到libc++,开发人员还应审核项目依赖项,以删除对libstdc++的引用

  6. Libgcc已经过时了。Xcode 10无法再构建具有macOS 10.4和10.5部署目标的应用程序。(42818150,38035243)

  7. 已删除对Subversion(SVN)的支持,目前只支持Git

  8. Xcode 10是最后一个支持Swift 3的版本。通过打开项目并选择Edit> Convert> To Current Swift Syntax ...将项目从Swift 3代码迁移到Swift 4.2语法...(43101816)

  9. macOS 10.14 SDK不再包含对编译32位应用程序的支持。如果开发人员需要为i386编译,则需要Xcode 9.4或更早版本。

  10. 调试工具增强
    更多信息请阅读参考文档中的《Xcode 10 Release Notes》

XCode10已知BUG

  1. 打开存储在iCloud Drive中的Xcode项目和工作空间,或更改存储在iCloud Drive中的打开的工作空间或项目的源控制分支,可能会导致Xcode挂起。
  2. 运行iOS 12的设备可能无法从Xcode的设备窗口获取请求的屏幕截图。(42873539)
    解决方法:在设备上截取屏幕截图。
  3. 使用以前版本的Xcode构建的Xcode 10运行WatchKit应用程序可能会出现安装错误“WatchKit应用程序具有无效的存根可执行文件”。(40567857)
    解决方法:清理构建文件夹并再次运行应用程序。
  4. 如果Xcode尚未连接完成任何开发设备,则Instruments可能无法启动。(43066159)
    解决方法:等待Xcode的设备设置阶段完成,然后打开Instruments。
  5. Instruments可能无法在iOS模拟器中配置库或框架单元测试
  6. 在playground中切换到非默认工具链可能会导致Xcode崩溃。(43659135)
    解决方法:切换回默认工具链,然后打开playground。
  7. 模拟设备中的macOS粘贴板和粘贴板之间的同步有时会失败。(36036706,38052949,41916640)
  8. 操作系统可能需要几分钟才能在模拟器中首次启动。(40535421)
  9. Xcode不支持ed25519加密的SSH密钥对。(40912136)
    解决方法:使用使用不同加密形式的SSH密钥对。

参考文档

1.whats-new-in-swift-4-2
2.swift change Log
3.swift-4-2-released
4.Xcode 10 Release Notes

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