「WWDC2018」-Cocoa Touch革新What's New in Cocoa Touch

這篇文章是對WWDC2018關於Cocoa Touch新特性的翻譯與總結。在What's New in Cocoa Touch這個session中,主要分為三個topic來講的,下面一個一個來看。

一、Framework updates

一、性能優化方面

1、scrolling

在iOS12中首先對scrollview的滑動做了預加載數據CPU計算優化。主要以UITableview的加載來進行了舉例。UITableview在顯示的時候分為這幾步。

  1. 先從緩存隊列中取出一個cell或者是直接創建一個cell
  2. 將model數據傳入cell,而這一步具體的消耗如何就要看數據的獲取方式了,你可能從數據庫中獲取,也可能從網絡中獲取,總之這可能是一個相當耗時的工作。
  3. cell調用layoutSubviews為子視圖佈局
  4. 調用draw()方法繪製view,也就是drawInRect方法進行繪製。這裡cell所有的子view都要調用一遍,我們還可能填充文字等,所以這一步也可能需要較大的時間開銷

在這種cell的展示方式中,這四步都必須要在cell展示的那一幀時間內(1/60秒)完成,才能保證不卡頓。為了讓cell計算的速度儘可能快,所以在iOS12中有了prefetch API,這個API可以提前異步的去進行數據的獲取,所以在滑動的時候繪製Cell那一幀時間裡就省去了數據獲取的步驟,只負責cell的繪製就夠了,這樣就大大節省了CPU的開銷。

在UITableViewDataSourcePrefetching這個protocol中,也就兩個方法:

protocol UITableViewDataSourcePrefetching { func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) func tableView(_ tableView: UITableView, cancelPrefetchingForRowsAt: indexPaths [IndexPath])}

這兩個方法中必須實現的就是prefetchRowAt這個方法,你可以把一些耗時的數據獲取工作放在這個方法中。這樣就可以在cell顯示之前提前獲取數據而不用等到cell繪製的時候另外佔用CPU開銷。

後面發現了一個case。如果在cell load過程中同時進行prefetch,就會造成在繪製當前cell的時候既要load當前cell,還要去prefetch下一個即將顯示的cell,這樣就會造成繪製當前cell的時候CPU開銷太大。

「WWDC2018」-Cocoa Touch革新What's New in Cocoa Touch

所以在後面有了改進,如下圖所示,它是在當前cell load完成的時候去異步prefetch下一個cell的數據的。這樣就避免prefetch對當前cell繪製的影響。

「WWDC2018」-Cocoa Touch革新What's New in Cocoa Touch

另外還發現了一個case,如果在設備並沒有滿載的時候,這個時候只是運行了一個簡單的前臺程序的滑動工作,CPU並不知道將來的工作到底如何,它可能就會使用盡可能低的level進行工作以進行省電。但是這個時候如果來了複雜的計算(需要繪製複雜的cell),等CPU提高level再去進行計算,可能就會太遲了,就很容易造成卡頓。這個時候CPU的工作方式如圖:

「WWDC2018」-Cocoa Touch革新What's New in Cocoa Touch

因此在iOS12中,會提前把要繪製的信息告訴CPU,如果有複雜的任務,CPU就會提前進入高的level,這樣提前瞭解App需要的CPU佔用情況,就能讓CPU及時改變它的level。所以在iOS12中CPU會盡可能的根據你的應用的需求情況來進行調整,這樣在達到了省電的同時還能充分利用CPU保證流暢性,確實很棒!

「WWDC2018」-Cocoa Touch革新What's New in Cocoa Touch

2、Memory

首先強調了一下memory對性能影響的重要性,然後介紹了一下App在運行的時候,內存的使用情況

「WWDC2018」-Cocoa Touch革新What's New in Cocoa Touch

當你請求一個小的內存的時候,此時內存足夠,就會直接獲取free memory,但是現在當你的App申請一個較大的內存的時候,這個時候就很可能內存不足,系統就會從Other Apps and System中去獲取,也就是其它那些在後臺中的進程。雖然這能滿足我們的需求,但它仍然可能在其它地方產生未知的影響。而且這個過程對於我們的App來說依然會佔用很多時間,所以其實對我們的應用也是有影響的。因此找到一些方法來節約內存對於我們的App來說會有很大的提升。下面就講到了iOS12中對圖片的一個優化。

「WWDC2018」-Cocoa Touch革新What's New in Cocoa Touch

以上面兩個圖來說,他們的內存大小都是每個像素64位這樣來計算的。但其實第二張圖並沒有完全利用所有的color位數,因為它只有黑白兩種顏色,顯然這造成了對內存的浪費。所以在iOS12中只使用了8位,所以第二種圖片在使用了Automatic Backing Store後的內存佔用縮減成了下面這樣,這對於App的內存佔用是一個很大的提高。

「WWDC2018」-Cocoa Touch革新What's New in Cocoa Touch

Automatic Backing Store在iOS12的SDK中默認會在下面這三種方法中進行

  • UIView.draw()
  • UIGraphicsImageRenderer
  • UIGraphicsImageRenderFormat.Range

所有與圖片渲染相關的API都可以使用Automatic Backing Store,如果想要了解詳細使用情況的話,可以看這個session(Image and Graphics Best Practices)

3、autolayout

Autolayout在iOS12中也進行了較大的提升。

首先是對於互不相關的兄弟視圖來說,雖然在iOS12之前隨著視圖的增多計算的複雜度就已經是線性增加的了,但是iOS12中通過團隊的努力還是把計算複雜度盡其所能的進行了降低。

「WWDC2018」-Cocoa Touch革新What's New in Cocoa Touch

然後再說更加複雜的約束相互有依賴的視圖,iOS12之前隨著視圖的增多,frame的計算複雜度是在呈指數上漲的。所以之前使用autolayout的話性能瓶頸是很明顯的,稍微複雜一點的視圖我們可能都會放棄autolayout。但是在iOS12中,autolayout的計算不再呈指數上漲了。通過優化也已經實現線性增加的複雜度。對於嵌套視圖來說,也是如此,複雜度由指數級下降至線性級。

「WWDC2018」-Cocoa Touch革新What's New in Cocoa Touch

這樣一來,iOS12以後使用autolayout我們也不用太擔心性能瓶頸問題了

,這確實是一件值得興奮的事。

二、Swiftification

主要講了swift有以下幾點增強,總結一下就是讓swift感覺更加swift了。

  • Types
  • 主要就是一些全局type加入到了類中,讓我們使用起來更加方便。下面給了一些例子:
// Swift 4enum UIApplicationState { case active case inactive case background}// Swift 4.2class UIApplication : UIResponder { enum State { case active case inactive case background }}// Swift 4enum UITabBarItemPositioning { case automatic case fill case centered}// Swift 4.2class UITabBar : UIView { enum ItemPositioning { case automatic case fill case centered }}
  • Constants
  • 一些全局常量也被加入到了相關類中,如下面一些例子:
// Swift 4class NSNotification : NSObject { struct Name { class let didChangeStatusBarOrientation: NSNotification.Name }}let UIApplicationStatusBarOrientationUserInfoKey: String// Swift 4.2class UIApplication : UIResponder { class let didChangeStatusBarOrientationNotification: NSNotification.Name class let statusBarOrientationUserInfoKey: String}// Swift 4let UIFloatRangeZero: UIFloatRangelet UIFloatRangeInfinite: UIFloatRange// Swift 4.2struct UIFloatRange { static let zero: UIFloatRange static let infinite: UIFloatRange}
  • Fundations
  • 還有一些全局函數也被移進了相關類中,如下一些例子:
let insets = UIEdgeInsets(top: 8, left: 0, bottom: 8, right: 0)let image = UIImage(named: “Apple”)// Swift 4let insetRect = UIEdgeInsetsInsetRect(originalRect, insets)let pngData = UIImagePNGRepresentation(image)// Swift 4.2let insetRect = originalRect.insetBy(insets)let pngData = image.pngData()// Swift 4NSStringFrom[CGPoint, CGRect, CGSize, CGVector, CGAffineTransform, UIEdgeInsets, UIOffset][CGPoint, CGRect, CGSize, CGVector, CGAffineTransform, UIEdgeInsets, UIOffset]FromString// Swift 4.2 – Codable Conformancelet encoded = JSONEncoder().encode(CGPoint(x: 0, y: 0))let decoded = JSONDecoder().decode(CGPoint.self, from: encoded)// Swift 4NSStringFrom[CGPoint, CGRect, CGSize, CGVector, CGAffineTransform, UIEdgeInsets, UIOffset][CGPoint, CGRect, CGSize, CGVector, CGAffineTransform, UIEdgeInsets, UIOffset]FromString// Swift 4.2 — Codable Conformancelet encoded = JSONEncoder().encode(CGPoint(x: 0, y: 0))let decoded = JSONDecoder().decode(CGPoint.self, from: encoded)// Swift 4.2 — Debug Printingprint(CGPoint(x: 0, y: 0))print(“Offset: \(UIOffset(horizontal: 10, vertical: 10))”)// Swift 4NSStringFrom[CGPoint, CGRect, CGSize, CGVector, CGAffineTransform, UIEdgeInsets, UIOffset][CGPoint, CGRect, CGSize, CGVector, CGAffineTransform, UIEdgeInsets, UIOffset]FromString// Swift 4.2 — Codable Conformancelet encoded = JSONEncoder().encode(CGPoint(x: 0, y: 0))let decoded = JSONDecoder().decode(CGPoint.self, from: encoded)// Swift 4.2 — Debug Printingprint(CGPoint(x: 0, y: 0))print(“Offset: \(UIOffset(horizontal: 10, vertical: 10))”)// Swift 4.2 — Legacy Encoding/Decodinglet encoded = NSCoder.string(for: CGPoint(x: 0, y: 0))let decoded = NSCoder.cgPoint(for: encoded)

另外還增加了安全的編解碼API,但是這裡並沒有詳細介紹,如果想要了解的話可以看這篇session(Data You Can Trust)

二、API 的改善

1、通知

在iOS12中通知有了很多很大的提升,但是今天只講以下三個方面。

  • 交互

iOS12在通知中可以有更多的交互,現在的交互動作也不再是靜態的,比如iMessage甚至可以直接回覆信息

「WWDC2018」-Cocoa Touch革新What's New in Cocoa Touch

  • 消息分組

iOS中的notification已經默認支持分組,也就是說默認情況下一個應用的通知都會被分為一個group進行展示。當然你也可以進行個人定製,可以通過給通知標記thread identifier,這樣所有有相同的thread identifier的通知都會出現在同一個group。

「WWDC2018」-Cocoa Touch革新What's New in Cocoa Touch

  • 設置

iOS12新的的通知UI增加了Notification settings。Notification settings支持用戶根據他們自己的行為定製個性化的通知,或者

你也可以通過iOS12中一個新的API來為用戶深入定製與你應用相關的setting。

「WWDC2018」-Cocoa Touch革新What's New in Cocoa Touch

更多與Notification相關的內容可以查看這兩個sessionWhat’s New in User Notifications

和Using Grouped Notifications

2、短信

在iOS12中iMessage增加了camera中的一些新特性,只要我們在xcode中創建sticker template,我們創建的貼紙就會自動加入messages和相機中。除此之外,如果你想創建更加定製化的貼紙的話,你可以使用MSMessages App ViewController,並在info.plist中配置如下參數

MSSupportedPresentationContexts  MSMessagesAppPresentationContextMessages  MSMessagesAppPresentationContextMedia

這兩個參數讓你的貼紙既可以在messages中使用,也可以在相機中使用,當然你也可以選擇某一個。

你可以通過以下新的API判斷你的messages app是處於messages中還是相機中。

enum MSMessagesAppPresentationContext : UInt {  case messages  case media }

還有一個小改動就是之前左右滑動會進行messages app的切換,現在左右滑動的手勢不會產生切換了,也就是說你的messages app支持左右滑動了。(這個對比一個iOS11和iOS12的iMessage就可以看到)

3、密碼和驗證碼的自動填充

在iOS12中,你只需要將你的登錄輸入框設置為password text content type或者將註冊輸入框(密碼修改輸入框)設置為new password text content type,系統就會自動識別,提示用戶將密碼存入iCloud的keychain中,並且在用戶下次輸入的時候自動填充密碼。

「WWDC2018」-Cocoa Touch革新What's New in Cocoa Touch

「WWDC2018」-Cocoa Touch革新What's New in Cocoa Touch

另外在短信驗證中,獲取驗證碼後也就不用來回切換app了,系統會自動識別驗證碼。

「WWDC2018」-Cocoa Touch革新What's New in Cocoa Touch

總之,在strong passwords的使用下,我們再也不用為各種各樣的密碼和驗證碼而煩惱啦。

4、安全區以(safeArea)

safeArea可以確保我們的內容不會超出內容正確顯示範圍,比如一些top bar,bottom bar啥的。safeArea的計算其實是非常複雜的,它會根據不同的設備進行不同的比例縮放。總之它給了我們一個安全的區域讓我們去填充我們的視圖。

「WWDC2018」-Cocoa Touch革新What's New in Cocoa Touch

「WWDC2018」-Cocoa Touch革新What's New in Cocoa Touch

safeArea其實不是什麼新內容,不過這裡再次強調可以看出蘋果對safeArea的重視,而且蘋果官方很鼓勵我們去使用safeArea,所以我們以後自定義視圖的時候一定要注意根據safeArea去佈局,不要超出safeArea的範圍。

最後有一個相關的session推薦UIKit: Apps for Every Size and Shape

三、Siri shortcuts

iOS12中新增的主要有兩個API,這兩個API讓你不僅可以與Siri有一些常見的簡單的互動,還可以在一些複雜的場景中有一些更加定製化的互動。

1、NSUserActivity

NSUserActivity是一個簡單的API,它可以被用於簡單的切換和喚起。雖然簡單,但是在一些場景中它也可以發揮巨大的作用,比如你可以通過它返回到應用中的某一指定頁面。比如你正在看某一條信息或者文件的時候,可以通過它在另一個設備跳轉到相同的位置。而是用起來也很簡單,只需要一行代碼搞定

Set eligibleForPrediction = true

2、SiriKit

如果你想使用更多定製化的內容的話,就可以使用它了。它包含的內容很多,如圖所示:

「WWDC2018」-Cocoa Touch革新What's New in Cocoa Touch

在iOS12中,你可以定義自己的內容。


分享到:


相關文章: