Framework Updates
Performance: Scrolling
iOS中的Scrolling基本遵循同样的模式:We load content to be displayed into the views and then we're just moving that content around。大多数情况下这个操作的开销很小,因为不需要加载新的内容,但是当一个新的视图第一次变为可见时,它会突然间加载大量的内容,从而导致CPU突然间的峰值使用:
下面使用 UI Table View 来解释这种开销突然变大的原因:
// UITableView Cell Load Cost
import UIKit
class MyTableViewDataSource {
func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Dequeue or allocate cell
// Populate cell with model data
return myCell
}
}
// call layoutSubviews on UIViews in the cell
// call draw() on UIViews in the cell
在 "Populate cell with model data"阶段可能包含一些开销比较大的操作,比如读取文件、从数据库加载数据等。并且除此之外,单元格的准备和显示、在单元格中布置内容、视图的大小和位置等等,并且这些需要在限定的时间内完成(16 milli-seconds for 60-hertz devices, 8 milli-seconds for 12-hertz iPads, iPad Pro)
iOS 10 中引入了 Pre-Fetching
API 来处理这个问题,通过提前获取以及背景线程获取的方式来处理文件的读取和数据库的加载:
// UITableView Pre-Fetching
protocol UITableViewDataSourcePrefetching {
func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath])
func tableView(_ tableView: UITableView,
cancelPrefetchingForRowsAt: indexPaths [IndexPath])
}
但是事实上这个导致了一个意想不到的问题:如果当前帧加载的操作不能在相应的时间内完成的话 (16 milli-seconds, 8 milli-seconds),下一帧会同时开始加载,就会引起掉帧或者页面滚动故障的现象。这是因为CPU事实上被同时应用于当前帧 (Current Frame)以及未来帧 (Future Frame) 的加载,从而导致了CPU资源使用的相互竞争,以至于两者事实上都花费了更长的时间。
iOS 12 中会更加智能的安排背景线程的使用,比如变为串行加载,避免与当前线程的产生冲突。
另外一个意外的问题是:在没有太多背景线程消耗的情况下也会产生掉帧。这是因为iOS会在不需要立即需要的时候停止背景线程的运行,这就导致我们需要显示下一帧的时候,CPU才会匆忙的去调用背景线程加载数据,这样导致这个操作不一定能够在限定时间内完成从而导致掉帧。
iOS 12 对此在最底层的CPU控制上进行了优化,会更加智能的预见可能发生的消耗以及平衡CPU的使用,使得操作能够在限定时间内完成从而避免掉帧。
而对于我们开发而言,这就要求我们:
使用 "Prefetching API" (Table View, Collection View) 提前准备好数据
设计上就尽减少单元格所需的加载数据以及所需的操作
Performance: Memory
iOS 12 中新引入了 Automatic Backing Store 可以根据内容本身的深度来降低内存的使用,比如对于同样一张图片,在高保真("Full Fidelity")和低保真("Lower Fidelity")状态下,调整 BPP (Bits Per Pixel)像素值来减少需要占用的内存:
现在ABS已经在iOS 12中默认开启,当然如果需要的话,也可以自己设定Backing Store Style:
Automatic is now default
• UIView.draw()
• UIGraphicsImageRenderer
• UIGraphicsImageRendererFormat.Range
Performance: Auto Layout
iOS 12 中极大提高了 Auto Layout 的性能,视频列了三个例子:"Independent Sibling View", "Dependent Sibling Views" 以及 "Nested Views"。
Framework Updates: Swiftification
Swift 4.2 支持了 4.0中不支持的嵌套方式:
Nested Types
// Swift 4
enum UITabBarItemPositioning {
case automatic
case fill
case centered
}
// Swift 4.2
class UITabBar : UIView {
enum ItemPositioning {
case automatic
case fill
case centered
}
}
Nested Constants
// Swift 4
class NSNotification : NSObject {
struct Name {
class let didChangeStatusBarOrientation: NSNotification.Name
}
}
let UIApplicationStatusBarOrientationUserInfoKey: String
// Swift 4.2
class UIApplication : UIResponder {
class let didChangeStatusBarOrientationNotification: NSNotification.Name
class let statusBarOrientationUserInfoKey: String
}
Nested Functions
let insets = UIEdgeInsets(top: 8, left: 0, bottom: 8, right: 0)
let image = UIImage(named: “Apple”)
// Swift 4
let insetRect = UIEdgeInsetsInsetRect(originalRect, insets)
let pngData = UIImagePNGRepresentation(image)
// Swift 4.2
let insetRect = originalRect.insetBy(insets)
let pngData = image.pngData()
Framework Updates: NSSecureCoding
引入了新的 "secure-by-default encoding and decoding APIs",具体参见 "Data You Can Trust"演讲。
API Enhancements
Notifications
Interaction 在Notification中直接回复消息:
Grouping 同一个APP的通知组织在一起:
甚至可以使APP某一类通知放在一起,与其他通知区别开来。
Settings 更方便的设置
更多的信息可以参见 "What's New in User Notifications" 和 "Using Grouped Notifications" 演讲。
Messages
支持 Presentation Context,让你知道是在 Message 还是 Media 中;以及 Message 直接内嵌到你的APP中,避免APP的切换。
Automatic Passwords and Security Code AutoFIll
支持用户的APP使用iCloud同步密码;支持密码的自动填充,包括自动读取2factor的验证代码;甚至支持根据特定要求的新密码的自动创建。
Safe Area
更强大的 Safe Area,比如iPad的 Split View,以及更好的适应IPhoneX:
Siri Shortcuts
支持自定义的 Siri Shortcuts:
使用此功能可以在APP中自定义功能与短语的对应关系并加入到Siri Shortcuts中,以便可以在不唤醒APP的情况下,更智能的使用Siri调用我们APP中相应的功能。