源码阅读之 Alamofire (2)

274 阅读3分钟

Session.swift

单例模式

default == shareInstance

原理

底层使用URLSession 对象创建URLSessionTask,并且作为单例代理的处理回调参数。

代理对象是SessionDelegate对象。

rootQueue是dispatch_queue队列。

构造函数

public init(session: URLSession,

                delegate: SessionDelegate,

                rootQueue: DispatchQueue,

                startRequestsImmediately: Bool = true,

                requestQueue: DispatchQueue? = nil,

                serializationQueue: DispatchQueue? = nil,

                interceptor: RequestInterceptor? = nil,

                serverTrustManager: ServerTrustManager? = nil,

                redirectHandler: RedirectHandler? = nil,

                cachedResponseHandler: CachedResponseHandler? = nil,

                eventMonitors: [EventMonitor] = []) {

        precondition(session.configuration.identifier == nil, "Alamofire does not support background URLSessionConfigurations.")

        precondition(session.delegateQueue.underlyingQueue === rootQueue,"Session(session:) initializer must be passed the DispatchQueue used as the delegateQueue's underlyingQueue as rootQueue.")
        self.session = session

        self.delegate = delegate

        self.rootQueue = rootQueue

        self.startRequestsImmediately = startRequestsImmediately

        self.requestQueue = requestQueue ?? DispatchQueue(label: "\(rootQueue.label).requestQueue", target: rootQueue)

        self.serializationQueue = serializationQueue ?? DispatchQueue(label: "\(rootQueue.label).serializationQueue", target: rootQueue)

        self.interceptor = interceptor

        self.serverTrustManager = serverTrustManager

        self.redirectHandler = redirectHandler

        self.cachedResponseHandler = cachedResponseHandler

        eventMonitor = CompositeEventMonitor(monitors: defaultEventMonitors + eventMonitors)

        delegate.eventMonitor = eventMonitor

        delegate.stateProvider = self

    }

知识点

  1. swift的 convenience 是啥?

在 Swift 编程语言中,关键字 convenience 用于修饰类的构造函数(initializer),表示这个构造函数是一种便利构造函数,即用于方便用户创建对象的构造函数。 便利构造函数的特点是:

  • 它们必须调用同一个类中的其它构造函数,并且在调用前必须使用 self.init 关键字。
  • 它们不能直接调用父类的构造函数或者给属性赋值。如果需要调用父类的构造函数或者给属性赋值,需要在 self.init 后面使用点语法来调用。

使用 convenience 关键字修饰构造函数可以简化代码,提高代码的可读性和可维护性。 eg.

class Person {
    var name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
    convenience init(name: String) {
        self.init(name: name, age: 0)
    }
}

销毁函数 (析构函数)

deinit {
        finishRequestsForDeinit()
        session.invalidateAndCancel()
    }

在 Swift 中,deinit 是一个特殊的方法,用于在对象被销毁(释放内存)之前执行清理工作,类似于其他编程语言中的析构函数(destructor)。 deinit 方法没有参数和返回值,它会在对象的引用计数归零时自动调用,无法手动调用。当对象的引用计数为 0 时,表示没有任何强引用指向该对象,此时系统会自动调用 deinit 方法来释放对象所占用的内存和资源。 eg.

class MyClass {
    var name: String
    
    init(name: String) {
        self.name = name
    }
    
    deinit {
        print("对象 \(self.name) 被销毁了")
    }
}

var obj1: MyClass? = MyClass(name: "obj1")
var obj2 = obj1
obj1 = nil
obj2 = nil // 会自动调用 deinit 方法

All Requests API

public func withAllRequests(perform action: @escaping (Set<Request>) -> Void){
        rootQueue.async {
            action(self.activeRequests)
        }
    }

知识点【语法】 perform: 在这段 Swift 代码中,perform 是一个参数标签(parameter label),用于标识函数参数 action 的作用。

参数标签是 Swift 中的一个特性,用于提高函数的可读性和可理解性。在函数定义中,参数标签通常会在参数名之前,用以描述这个参数的作用和含义。在调用函数时,需要使用参数标签来指定每个参数的作用,以便增强代码的可读性和可维护性。

在这个函数中,参数标签 perform 表示这个闭包参数 action 的作用是执行一些操作。通过使用参数标签,我们可以清晰地知道这个参数的作用,从而更加容易理解这个函数的意义和用法。

@escaping: 这个关键字用于告诉编译器,这个闭包可能会在函数结束之后仍然被执行,因此需要将它保存在堆上而不是栈上。在这个函数中,由于闭包被异步执行,因此需要使用 @escaping 关键字来修饰这个闭包参数。

(Set<Request>) -> Void:一个闭包类型,它接受一个参数 Set<Request>,表示一个由 Request 对象组成的集合,返回 Void 表示不返回任何值。这个闭包类型的作用是在函数中执行一些操作,使用传递进来的 Set<Request> 参数作为输入。 perform action::这个参数的名字为 action,是一个闭包类型的参数。

其他

open class Session{}

open 代表着什么意思?