What‘s new in Swift
Swift 生态提升:
- Swift Package Index
- Swift Package Collections
- Swift System
- Swift on Server
- Swift DocC,未来支持所有 Swift Projects
- Build 提升,局部编译优化,主要针对 SwiftUI
- Optimize Object Lifetimes
- enum Codable 优化,泛型语法优化<T: X>, .xProperty
- propertyWrapper 在 function 中使用
- SwiftUI 中使用条件编译优化
#if os(macOS)
.toggleStyle(.checkbox)
#else
.toggleStyle(.switch)
#endif
- async/await actor
- Swift 6 进行中
- 多 window 任务,UIWindowScene
- UICollectionView 滑动多选
- 提升 keyCommands
- Drag and Drap
- UIButton.Configuration
- TextKit 2
- UIScene 恢复状态
- cell.configurationUpdateHander
- 自定义 copy pause 提示,注重隐私
What's new in Foundation
ARC in Swift: Basics and beyond
/// Evaluates a closure while ensuring that the given instance is not destroyed
/// before the closure returns.
///
/// - Parameters:
/// - x: An instance to preserve until the execution of `body` is completed.
/// - body: A closure to execute that depends on the lifetime of `x` being
/// extended. If `body` has a return value, that value is also used as the
/// return value for the `withExtendedLifetime(_:_:)` method.
/// - Returns: The return value, if any, of the `body` closure parameter.
@inlinable public func withExtendedLifetime<T, Result>(_ x: T, _ body: () throws -> Result) rethrows -> Result
Explore WKWebView additions
Your guide to keyboard layout
async await
Task detached, 异步执行任务
func persistentPosts() async throws -> [Post] {
typealias PostContinuation = CheckedContinuation<[Post], Error>
return try await withCheckedThrowingContinuation { (continuation: PostContinuation) in
self.getPersistentPosts { posts, error in
if let error = error {
continuation.resume(throwing: error)
} else {
continuation.resume(returning: posts)
}
}
}
}
Protect mutable state with Swift actors
每当从外部与 Actor 互动的时候,都是异步进行的。
如果 Actor busy,代码将挂起,CPU 可以进行其他工作。
当 Actor 再次获得资源后,会继续执行。
actor Work {
var a = 10
func run() -> Int {
a += 1
return a
}
}
let work = Work()
Task {
print(1, await work.run())
print(1, await work.a)
}
Task {
print(2, await work.run())
print(2, await work.a)
}
// 1 11
// 2 12
// 1 12
// 2 12
如代码中的打印数据
Sendable:
Value Type
Actor Type
不可变的类 (不包含可变属性)
内部执行同步的类(如内部使用 lock 来实现并行)
@Sendable function types, 意味着任何相关的变量都要是 Sendable 的
let a = A()
Task.detached {
print(Thread.current)
await a.run()
print(Thread.current)
}
如果 A 是 Cocoa 或者 UIKit 的子类, 则在执行到 A 的 async 方法时,会自动切换到主线程,并且之后的任务同样在主线程中执行
class A: NSView {
func run() async {
print(Thread.current)
}
}
// <NSThread: 0x60000099c840>{number = 2, name = (null)}
// <_NSMainThread: 0x600000990900>{number = 1, name = main}
// <_NSMainThread: 0x600000990900>{number = 1, name = main}
如果 A 不是和 UI 相关的子类,则不会切回主线程
class A {
func run() async {
print(Thread.current)
}
}
// <NSThread: 0x6000035f0200>{number = 2, name = (null)}
// <NSThread: 0x6000035f0200>{number = 2, name = (null)}
// <NSThread: 0x6000035f0200>{number = 2, name = (null)}
Main Actor:
使用 @MainActor 标记的类,这个类的所有执行都在主线程
@MainActor class A {
func run() {
print(Thread.current)
}
}
// <NSThread: 0x60000293cf40>{number = 2, name = (null)}
// <_NSMainThread: 0x600002958e40>{number = 1, name = main}
// <NSThread: 0x60000293cf40>{number = 2, name = (null)}
nonisolated:
可以使用 nonisolated 来标记某个方法不在主线程执行
@MainActor class A {
nonisolated func run() {
print(Thread.current)
}
}
// <NSThread: 0x600000585a40>{number = 2, name = (null)}
// <NSThread: 0x600000585a40>{number = 2, name = (null)}
// <NSThread: 0x600000585a40>{number = 2, name = (null)}
Explore structured concurrency in Swift
Task Group 的使用
func fetchThumbnails(for ids: [String]) async throws -> [String: UIImage] {
var thumbnails: [String: UIImage] = [:]
try await withThrowingTaskGroup(of: (String, UIImage).self) { group in
for id in ids {
group.async {
return (id, try await fetchOneThumbnail(withID: id))
}
}
// Obtain results from the child tasks, sequentially, in order of completion.
for try await (id, thumbnail) in group {
thumbnails[id] = thumbnail
}
}
return thumbnails
}
Task detached, 异步执行任务
Task.detached(priority: .background) {
await withTaskGroup(of: Void.self) { group in
group.addTask { print(1, Thread.current) }
group.addTask { await self.run() }
group.addTask { print(2, Thread.current) }
}
}
Meet AsyncSequence
异步的 Sequence
let values = AsyncStream(Int.self) { con in
con.yield(1)
con.yield(2)
con.yield(3)
}
for await i in values {
print(i)
}
Swift concurrency: Behind the scenes
Cooperative thread pool:
控制线程数量不大于 CPU 数量,避免线程过多造成的上下文频繁切换。
await 和 原子:
await 不要持有任何锁。
线程私有数据也不会在 await 过程中保留。
async/await 对比锁的优势,编译期间,编译器会帮助检查使用的正确性。
在 await 中使用锁要非常小心。
不要在 await 中使用信号量, 如下代码:sem.signal 永远执行不到。
func run1() async {
print(3, Thread.current)
}
override func viewDidLoad() {
super.viewDidLoad()
let sem = DispatchSemaphore(value: 0)
Task.detached {
await self.run1()
sem.signal()
}
sem.wait()
}
SwiftUI:
What's new in SwiftUI
SwiftUI Accessibility: Beyond the basics
Direct and reflect focus in SwiftUI
Localize your SwiftUI app
Bring Core Data concurrency to Swift and SwiftUI
Discover concurrency in SwiftUI
Demystify SwiftUI
Development
Meet TestFlight on Mac
Meet Xcode Cloud
Explore Xcode Cloud workflows
Customize your advanced Xcode Cloud workflows
Review code and collaborate in Xcode
Distribute apps in Xcode with cloud signing
Meet the Swift Algorithms and Collections packages
New:
Capture high-quality photos using video formats
Design for Group Activities
Extract document data using Vision
Discover Web Inspector improvements
Develop advanced web content
Create image processing apps powered by Apple Silicon
Build custom experiences with Group Activities
What’s new in camera capture
What's new in Wallet and Apple Pay
What's new in App Analytics
Secure login with iCloud Keychain verification codes
Qualities of great iPad and iPhone apps on Macs with M1
Improve global streaming availability with HLS Content Steering
Explore low-latency video encoding with VideoToolbox
Support customers and handle refunds
Manage in-app purchases on your server
Test:
Triage TestFlight crashes in Xcode Organizer
Explore Digital Crown, Trackpad, and iPad pointer automation
Embrace Expected Failures in XCTest
Diagnose unreliable code with test repetitions
Detect and diagnose memory issues
Ultimate application performance survival guide
Analyze HTTP traffic in Instruments
Doc
Host and automate your DocC documentation
Build interactive tutorials using DocC
Meet DocC documentation in Xcode
Design
What’s new in SF Symbols
Explore the SF Symbols 3 app
Create custom symbols
Symbolication: Beyond the basics
Watch
Connect Bluetooth devices to Apple Watch
网友评论