Alamofire反复返回列表页触发DidFinishCollectingMetrics崩溃求助
问题
我的应用包含列表页与详情页,在详情页的网络请求完成前反复点击导航栏返回按钮,Alamofire出现崩溃,完整崩溃日志如下:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[APMURLSessionDelegateProxy URLSession:task:didFinishCollectingMetrics:]: unrecognized selector sent to instance 0x282842000' *** First throw call stack: (0x180817d1c 0x19803cee4 0x1808e875c 0x1807b135c 0x1807b082c 0x180f84aa8 0x114b9c700 0x114b9dfc8 0x114ba5150 0x114ba5e10 0x114bb163c 0x1dbc20e10 0x1dbc2093c) libc++abi: terminating with uncaught exception of type NSException dyld4 config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/Developer/usr/lib/libBacktraceRecording.dylib:/Developer/usr/lib/libMainThreadChecker.dylib:/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[APMURLSessionDelegateProxy URLSession:task:didFinishCollectingMetrics:]: unrecognized selector sent to instance 0x282842000' terminating with uncaught exception of type NSException 23DF-26B4-45FA-95D9-D270455FA2D
已在闭包中使用弱引用以避免内存泄漏。
解决方案
1. 页面销毁时主动取消未完成请求
在详情页的deinit方法中,取消当前页面发起的所有Alamofire请求,切断URLSession后续回调:
class DetailViewController: UIViewController { private var dataRequest: DataRequest? func fetchData() { dataRequest = AF.request("your_request_url").responseJSON { [weak self] response in // 响应处理逻辑 } } deinit { dataRequest?.cancel() } }
2. 修复APM代理的方法缺失问题
崩溃核心原因是APMURLSessionDelegateProxy未实现iOS 10+新增的URLSession:task:didFinishCollectingMetrics:代理方法,可通过以下方式解决:
- 升级所用APM SDK至最新版本,新版本通常会补全所有必需的URLSession代理方法;
- 若为自定义APM代理类,手动添加该方法的空实现或转发逻辑:
extension APMURLSessionDelegateProxy: URLSessionTaskDelegate { func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) { // 空实现,或转发给原始代理对象 } }
3. 管理Alamofire Session生命周期
避免使用全局Session处理页面级请求,改为在详情页内创建独立Session实例,页面销毁时主动失效:
class DetailViewController: UIViewController { private var session: Session? override func viewDidLoad() { super.viewDidLoad() session = Session() } func fetchData() { session?.request("your_request_url").responseJSON { [weak self] response in // 响应处理逻辑 } } deinit { session?.invalidateAndCancel() } }
4. 临时异常捕获(治标方案)
若需紧急阻断崩溃,可在AppDelegate中添加全局异常捕获逻辑:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { NSSetUncaughtExceptionHandler { exception in if exception.name == NSInvalidArgumentException && exception.reason?.contains("URLSession:task:didFinishCollectingMetrics:") == true { // 忽略该特定异常 return } // 其他异常的上报或处理逻辑 } return true }
内容的提问来源于stack exchange,提问作者Özgür Ataseven
相关产品推荐
相关产品推荐

