WWDC 2019 Modern Swift API Design

No Prefixes in Swift0only Frameworks

C and Object-C symbols are global
Swift's module system allows disambiguation
Remember-each source file brings its imports into the same namespace

Values and references
Protocols and generics
Key path member lookup
Property wrappers

Classes

reference Type 相当于OC对象的引用

Structs

values Type 会拷贝整个

Enums

values Type 会拷贝整个

Choosing Reference or Values?

Prefer structs over classes
·Only choose classes when reference semantics are important
Classes can make a good choice when
·You need a reference counting and deinitialization
·The value is held centrally and shared
·Where is a separate notion of "identity" from "equality

RealityKit - Scenes and Entities

Values Types Make Copies of References

拷贝struct时,如果内部有引用类型,那么里面的引用类型只会进行浅拷贝,其他值类型则会进行深拷贝

Value and Reference Semantics
//可以通过这样暴露私有参数的内部参数
private var _texture: Texture

public var is Sparkly: Bool {
  get { _texture.isSparkly }
  set {
    // 检查,深复制
    if !isKnownUniquelyReferenced(&_texture) { _texture = Texture(copying: _texture) }
    _texture.isSparkly = newValue
  }
}

Protocols and Generics

Don't Literally Start With a Protocol

Start with concrete use cases
Discover a need for generic code
Try to compose solutions from existing protocols first
Consider a generic type instead of a protocol

SIMD? Scalar?

太多的协议,会造成编译速度变慢,因为会存在一个表里面

Key Path Member Lookup

Property Wrappers

Capture backing storage property and access policy for re-use

public struct MyType {
  @LateInitialized public var ...
//
}

Provides similar benefits to the built-in lazy
·Eliminates boilerplate
·Document semantics at the point of definition

@property Wrapper
public struct LateInitialized<Value> {
  private var storage: Value?
  
  public init() {
    storage = nil
  }

  public var value: Value {
    get {
      guard let value = storage else {
        fatalError("value has not yet been set!")
      }
      return value
    }
    set {
      storage = newValue
    }
  }
}

Using Property Wrappers

Use of property wrappers expand into a stored property and a computed property

public struct MyType {
  @LateInitialized public var text: String
  
  // Compiler-synthesized code...
  var $text: LateInitialized<String> = LateInitialized<String>()
  
  public var text: String {
    get { $text.value }
    
    set { $text.value = newValue }
  }
}
Using the DefensiveCopying Property Wrapper

@DefensiveCopying variables can be initialized in their declaration:

public struct MyType {
  @DefensiveCopying public var path: UIBezierPath = UIBezierPath() 
}

// Defensive Copying

@propertyWrapper

public struct DefensiveCopying<Value: NSCopying> {
  private var storage: Value

  public init(initialValue value: Value) {
    storage = value.copy() as! Value
  }

  public var value: Value {
    get { storage }
    set {
      storage = newValue.copy() as! Value
    }
  }
}

可以另外添加一个方法不进行拷贝初始化

extension DefensiveCopying {
  public init(withoutCopying value: Value) {
    storage = value
  }
}

Initializing the backing storage property:

public struct MyType {
  @DefensiveCopying public var path: UIBezierPath
  public init() {
    $path = DefensiveCopying(withoutCopying: UIBezierPath())
  }
}
API Design with Property Wrappers

Property wrappers describe the policy behind your data access Lots of API revolves around data access

@UserDefault(key: "BOOSTER_IGNITED", defaultValue: false)
static var isBoosterIgnited: Bool

@ThreadSpecific var localPool: MemoryPool //单独开一个线程存储,可以安全并且不需要考虑多线程的锁

Property Wrappers in SwiftUI

View data dependencies are expressed using property wrappers

struct SlideViewer: View { 
  @State private var isEditing = false
  @Binding var slide: Slide
  var body: some View {
    VStack {
      Text("Slide #\(slide.number)")
      if isEditing { 
        TextField($slide.title)
      }
      // ...
    } 
  }
}

内部实现

// Property Wrappers & Key Path Member Lookup
@propertyWrapper  @dynamicMemberLookup
public var value: Value {
  public struct Binding<Value> {
    get { ... }
    nonmutating set { ... }
}
  public subscript<Property>(dynamicMember keyPath: WritableKeyPath<Value, Property>) ->Binding<Property> { ... } //通过这个可以获取内部变量的@Binding属性
}
slide // Slide instance
slide.title // String instance
$slide // Binding<Slide> instance
$slide.title // Binding<String> instance 相当于 $slide[dynamicMember: \Slide.title]

Summary

Value semantics vs. reference semantics
Use protocols for code reuse — not classification
Property wrappers reuse computed property definitions

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

推荐阅读更多精彩内容