如何查看UnsafeMutablePointer<Int>的真实值?日期解析调试异常
问题分析与解决
核心问题
你遇到的超大数值是未初始化内存的垃圾值,根源有两个:
- 格式字符串与输入不匹配,导致
vsscanf解析失败,未成功写入部分字段的内存 - 分配的
UnsafeMutablePointer内存未初始化,解析失败时读取的是脏数据
你的输入字符串是"2022-09-21T09:01:00+01:00",但格式字符串"%d-%d-%dT%d:%d:%f%d:%dZ"存在两处错误:
- 时区部分的
+01:00没有匹配的符号格式符,直接用%d会跳过+号导致解析中断 - 输入末尾没有
Z,但格式字符串最后加了Z,完全不匹配
修复步骤
1. 修正格式字符串
匹配输入的格式,正确的格式字符串应为:
"%d-%d-%dT%d:%d:%f%+d:%d"
其中%+d用于匹配时区的正负号(+01中的+)。
2. 初始化分配的内存
UnsafeMutablePointer.allocate(capacity: 1)只会分配内存,不会初始化,解析失败时会读取到脏数据。需要在分配后立即初始化:
private static var year = UnsafeMutablePointer<Int>.allocate(capacity: 1) private static let month = UnsafeMutablePointer<Int>.allocate(capacity: 1) // ... 其他指针同理 // 初始化每个指针为0 year.initialize(to: 0) month.initialize(to: 0) day.initialize(to: 0) hour.initialize(to: 0) minute.initialize(to: 0) second.initialize(to: 0) hourOffset.initialize(to: 0) minuteOffset.initialize(to: 0)
注意:使用完指针后必须释放内存,避免泄漏:
defer { year.deinitialize(count: 1) year.deallocate() // ... 其他指针同理 }
3. 正确调试指针值
在Xcode调试器中,直接通过以下方式查看指针指向的真实值:
- 在代码中添加打印:
print("Year:", year.pointee) - 在调试控制台输入:
po year.pointee
修复后的完整代码示例
private static var components = DateComponents() private static var year = UnsafeMutablePointer<Int>.allocate(capacity: 1) private static let month = UnsafeMutablePointer<Int>.allocate(capacity: 1) private static let day = UnsafeMutablePointer<Int>.allocate(capacity: 1) private static let hour = UnsafeMutablePointer<Int>.allocate(capacity: 1) private static let minute = UnsafeMutablePointer<Int>.allocate(capacity: 1) private static let second = UnsafeMutablePointer<Float>.allocate(capacity: 1) private static let hourOffset = UnsafeMutablePointer<Int>.allocate(capacity: 1) private static let minuteOffset = UnsafeMutablePointer<Int>.allocate(capacity: 1) // 初始化内存 year.initialize(to: 0) month.initialize(to: 0) day.initialize(to: 0) hour.initialize(to: 0) minute.initialize(to: 0) second.initialize(to: 0) hourOffset.initialize(to: 0) minuteOffset.initialize(to: 0) // 确保释放内存 defer { year.deinitialize(count: 1) year.deallocate() month.deinitialize(count: 1) month.deallocate() day.deinitialize(count: 1) day.deallocate() hour.deinitialize(count: 1) hour.deallocate() minute.deinitialize(count: 1) minute.deallocate() second.deinitialize(count: 1) second.deallocate() hourOffset.deinitialize(count: 1) hourOffset.deallocate() minuteOffset.deinitialize(count: 1) minuteOffset.deallocate() } let parseCount = withVaList( [year, month, day, hour, minute, second, hourOffset, minuteOffset], { pointer -> Int32 in vsscanf("2022-09-21T09:01:00+01:00", "%d-%d-%dT%d:%d:%f%+d:%d", pointer) } ) // 打印解析成功的字段数,用于调试 print("Successfully parsed \(parseCount) fields") components.year = year.pointee components.minute = minute.pointee components.day = day.pointee components.hour = hour.pointee components.month = month.pointee components.second = Int(second.pointee) dump(components)
内容的提问来源于stack exchange,提问作者Karim
相关产品推荐
相关产品推荐

