判断输入是否为NSArray时Swift应用崩溃问题求助
问题描述
在执行类型检查input is NSArray时应用崩溃,相关代码如下:
private static func filter(input: Any?) -> Any? { guard let input = input else { return nil } if input is NSArray { // <- 此处崩溃 return nil } else { // 执行其他操作 } }
对应的崩溃日志:
Crashed: com.apple.root.user-initiated-qos.cooperative 0 libsystem_kernel.dylib 0xf3a4 __abort_with_payload + 8 1 libsystem_kernel.dylib 0x31c14 abort_with_payload_wrapper_internal + 104 2 libsystem_kernel.dylib 0x31bac abort_with_payload_wrapper_internal + 30 3 libobjc.A.dylib 0x33b74 _objc_fatalv(unsigned long long, unsigned long long, char const*, char*) + 116 4 libobjc.A.dylib 0x33b00 _objc_fatalv(unsigned long long, unsigned long long, char const*, char*) + 30 5 libobjc.A.dylib 0x8730 lookUpImpOrForward + 860 6 libobjc.A.dylib 0x2cc4 _objc_msgSend_uncached + 68 7 libswiftCore.dylib 0x4058d8 swift_dynamicCastObjCClassImpl(void const*, swift::TargetClassMetadata<swift::InProcess, swift::TargetAnyClassMetadataObjCInterop<swift::InProcess> > const*) + 44 8 libswiftCore.dylib 0x3b4484 tryCastFromObjCBridgeableToClass(swift::OpaqueValue*, swift::TargetMetadata<swift::InProcess> const*, swift::OpaqueValue*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetMetadata<swift::InProcess> const*&, swift::TargetMetadata<swift::InProcess> const*&, bool, bool) + 96 9 libswiftCore.dylib 0x3b3f38 tryCast(swift::OpaqueValue*, swift::TargetMetadata<swift::InProcess> const*, swift::OpaqueValue*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetMetadata<swift::InProcess> const*&, swift::TargetMetadata<swift::InProcess> const*&, bool, bool) + 2448 10 libswiftCore.dylib 0x3b3ca4 tryCast(swift::OpaqueValue*, swift::TargetMetadata<swift::InProcess> const*, swift::OpaqueValue*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetMetadata<swift::InProcess> const*&, swift::TargetMetadata<swift::InProcess> const*&, bool, bool) + 1788 11 libswiftCore.dylib 0x3b3434 swift_dynamicCast + 208 12 MyApp 0xe78f8c static MyLogic.filter(input:) + 92 (MyLogic.swift:92) 13 MyApp 0xe79a8c specialized static MyLogic.processParameters() + 45 (MyLogic.swift:45) 14 libswift_Concurrency.dylib 0x41948 swift::runJobInEstablishedExecutorContext(swift::Job*) + 416 15 libswift_Concurrency.dylib 0x42868 swift_job_runImpl(swift::Job*, swift::ExecutorRef) + 72 16 libdispatch.dylib 0x15944 _dispatch_root_queue_drain + 396 17 libdispatch.dylib 0x16158 _dispatch_worker_thread2 + 164 18 libsystem_pthread.dylib 0xda0 _pthread_wqthread + 228 19 libsystem_pthread.dylib 0xb7c start_wqthread + 8
解决思路
从崩溃栈来看,崩溃发生在Objective-C运行时的方法查找阶段,结合Swift类型检查逻辑,可从以下方向排查解决:
排查野指针问题:
input指向的内存已被释放,但Any?仍持有无效引用。执行is NSArray检查时需要发送isKindOfClass:消息,访问野指针触发崩溃。需确认input的生命周期,调用filter时对象是否仍有效;若来自Objective-C对象,检查内存管理是否存在未正确持有情况。检查类元数据损坏:输入对象的类信息被破坏(如内存越界、多线程读写同一对象),导致Runtime无法找到方法实现。需排查是否有代码修改该对象内存,或在多线程环境下对其进行非线程安全操作。
改用Swift原生类型检查:避免直接跨桥接检查
NSArray,换成Swift原生类型判断,降低桥接风险:// 方案1:检查是否为Swift Array if input is [Any] { return nil } // 方案2:先转为NSObject再判断 if let nsObj = input as? NSObject, nsObj is NSArray { return nil }添加对象有效性验证:导入Objective-C Runtime,用
objc_isValidObject在类型检查前验证对象合法性:import ObjectiveC private static func filter(input: Any?) -> Any? { guard let input = input else { return nil } if let obj = input as? NSObject, objc_isValidObject(obj) { if obj is NSArray { return nil } } // 执行其他操作 return input }排查异步调用风险:崩溃发生在并发队列,检查
processParameters()是否在异步任务中传递input,确保对象在异步执行期间未被提前释放。可使用weak引用或强持有对象直到任务完成。
内容的提问来源于stack exchange,提问作者Tometoyou
相关产品推荐
相关产品推荐

