@@ -10,7 +10,7 @@ import Foundation
1010import Network
1111import UIKit
1212
13- public final class STParameterEncoder {
13+ public enum STParameterEncoder {
1414
1515 public enum EncodingType {
1616 case url
@@ -126,7 +126,11 @@ open class STHTTPSession: NSObject {
126126 public let interceptor : STInterceptor ?
127127 public let eventMonitor : STCompositeEventMonitor
128128
129- private var urlSession : URLSession !
129+ private let urlSessionConfiguration : URLSessionConfiguration
130+ /// 底层 URLSession。init 中立即创建,避免 deinit 触发 lazy 初始化时把正在析构的
131+ /// self 注册为新 session 的 delegate(生命周期逃逸)。使用 Optional 存储:
132+ /// st_invalidate() 后置 nil,下次请求经 session 访问器惰性重建。
133+ private var urlSession : URLSession ?
130134 private let delegateQueue : OperationQueue
131135 private let stateLock = NSLock ( )
132136 private var requestsByTaskID : [ Int : STRequest ] = [ : ]
@@ -156,6 +160,7 @@ open class STHTTPSession: NSObject {
156160 eventMonitors: [ STEventMonitor ] = [ ] ,
157161 sslPinningConfig: STSSLPinningConfig = STSSLPinningConfig ( enabled: false )
158162 ) {
163+ self . urlSessionConfiguration = configuration
159164 self . defaultRequestConfig = defaultRequestConfig
160165 self . defaultRequestHeaders = defaultRequestHeaders
161166 self . interceptor = interceptor
@@ -177,11 +182,35 @@ open class STHTTPSession: NSObject {
177182 self . delegateQueue = queue
178183
179184 super. init ( )
180- self . urlSession = URLSession ( configuration: configuration , delegate: self , delegateQueue: self . delegateQueue)
185+ self . urlSession = URLSession ( configuration: self . urlSessionConfiguration , delegate: self , delegateQueue: self . delegateQueue)
181186 }
182187
183188 deinit {
184- self . urlSession. invalidateAndCancel ( )
189+ // 直接读取 Optional 存储,避免析构期触发 session 访问器的惰性重建。
190+ self . urlSession? . invalidateAndCancel ( )
191+ }
192+
193+ /// 返回当前可用的 URLSession;若已被 st_invalidate() 销毁则重建。
194+ /// 读取/创建/赋值与 st_invalidate() 经 stateLock 互斥,避免并发首次重建
195+ /// 产生多个 session,或取得刚被置空的旧 session。
196+ private var session : URLSession {
197+ self . withStateLock {
198+ if let session = self . urlSession {
199+ return session
200+ }
201+ let session = URLSession ( configuration: self . urlSessionConfiguration, delegate: self , delegateQueue: self . delegateQueue)
202+ self . urlSession = session
203+ return session
204+ }
205+ }
206+
207+ /// 显式销毁底层 URLSession 并释放其对 self 的 delegate 强引用,
208+ /// 打破 self ⇄ session 循环引用。调用后再次发起请求会重建一个新的 session。
209+ public func st_invalidate( ) {
210+ self . withStateLock {
211+ self . urlSession? . invalidateAndCancel ( )
212+ self . urlSession = nil
213+ }
185214 }
186215
187216 @discardableResult
@@ -370,7 +399,7 @@ open class STHTTPSession: NSObject {
370399 }
371400 request. urlRequest = adapted
372401
373- let task = self . urlSession . dataTask ( with: adapted)
402+ let task = self . session . dataTask ( with: adapted)
374403 request. task = task
375404 let restart : ( ) -> Void = { [ weak self] in
376405 Task { await self ? . executeData ( request, initial: initial, interceptor: interceptor, config: config) }
@@ -428,7 +457,7 @@ open class STHTTPSession: NSObject {
428457 }
429458 request. urlRequest = adapted
430459
431- let task = self . urlSession . uploadTask ( with: adapted, from: body)
460+ let task = self . session . uploadTask ( with: adapted, from: body)
432461 request. task = task
433462 let restart : ( ) -> Void = { [ weak self] in
434463 Task { await self ? . executeUpload ( request, initial: initial, body: body, interceptor: interceptor, config: config) }
@@ -483,9 +512,9 @@ open class STHTTPSession: NSObject {
483512
484513 let task : URLSessionDownloadTask
485514 if let resumeData = resumeData {
486- task = self . urlSession . downloadTask ( withResumeData: resumeData)
515+ task = self . session . downloadTask ( withResumeData: resumeData)
487516 } else {
488- task = self . urlSession . downloadTask ( with: adapted)
517+ task = self . session . downloadTask ( with: adapted)
489518 }
490519 request. task = task
491520 let restart : ( ) -> Void = { [ weak self, weak request] in
@@ -542,7 +571,7 @@ open class STHTTPSession: NSObject {
542571 }
543572 request. urlRequest = adapted
544573
545- let task = self . urlSession . dataTask ( with: adapted)
574+ let task = self . session . dataTask ( with: adapted)
546575 request. task = task
547576 let restart : ( ) -> Void = { [ weak self, weak request] in
548577 Task {
0 commit comments