Vapor 4.0.0 Beta 2 发布

更新日志

  • Services has been refactored to be more type-safe. (#2098)

Services, Container, and Provider have been replaced by a pattern built on Swift extensions. This is best explained with examples.

Telling Vapor to use Leaf:

import Leaf
import Vapor

// beta.1
s.register(ViewRenderer.self) { c in
    return c.make(LeafRenderer.self)
}

// beta.2
app.views.use(.leaf)

Registering a factory service:

// beta.1
s.register(Foo.self) { c in
    return Foo(...)
}
app.make(Foo.self).bar()

// beta.2
extension Application {
    var foo: Foo { 
        return Foo(...)
    }
}
app.foo.bar()

Registering a singleton service:

// beta.1
s.register(Foo.self) { c in
    return Foo(...)
}
app.make(Foo.self).bar = 0
app.make(Foo.self).bar += 1
print(app.make(Foo.self).bar) // 1

// beta.2
extension Application {
    var foo: Foo { 
        if let existing = self.storage[FooKey.self] as? Foo {
            return existing
        } else {
            let new = Foo()
            self.storage[FooKey.self] = new
            return new
        }
    }

    private struct FooKey: StorageKey { 
        typealias Value = Foo
    }
}

app.foo.bar = 0
app.foo.bar += 1
print(app.foo.bar) // 1

This new pattern of extending Application also works with Request:

extension Application {
    var foo: Foo { ... }
}

extension Request {
    var bar: Bar { 
        return self.application.foo.bar(for: self)
    }
}
  • Validations has been refactored to yield better and more type-safe errors (#2071)

  • Authentication methods are now grouped under a new req.auth helper (#2111)

  • All authenticators now accept Request in their authenticate methods (#2111)

  • Added new ErrorSource struct to the AbortError protocol (#2093)

This new struct makes it easier to pass around information about where an error came from. It also makes it easier to indicate that a given error has no source information. This helps the logger avoid muddying logs with useless error source information.

  • RouteBuilder HTTP method helpers now support an array of [PathComponent] (#2097)

  • User-provided HTTP headers are no longer ignored when using XCTVapor test methods (#2108)

  • Enabled test discovery on Linux (#2118)

iOS – UIView和CALayer的关系

CALayer 主要负责显示内容,继承自 NSObject

UIView 主要对 CALayer 做了简单的封装(UIView 类中有个成员变量 layer 就是 CALayer 类型)。另外,UIView 继承自 UIResponder 类,所以也会负责处理触摸事件的响应。

  • UIView 部分源码如下
open class UIView : UIResponder, NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem, UITraitEnvironment, UICoordinateSpace, UIFocusItem, UIFocusItemContainer, CALayerDelegate {

    open class var layerClass: AnyClass { get }

    public init(frame: CGRect)

    public init?(coder: NSCoder)

    open var isUserInteractionEnabled: Bool

    open var tag: Int

    open var layer: CALayer { get }

    @available(iOS 9.0, *)
    open var canBecomeFocused: Bool { get }

    @available(iOS 9.0, *)
    open var isFocused: Bool { get }

    @available(iOS 9.0, *)
    open var semanticContentAttribute: UISemanticContentAttribute

    ......
}

当对一个视图进行绘制的时候,绘图单元会向 CALayer 索取要显示元素的相关数据,此时, CALayer 会通过 delegate 通知到 UIView,看看 UIView 是否有提供需要绘制的元素。如果 UIView 什么都不需要提供的话,就当作无视。