Swift中MDQuerySetSortComparatorBlock正确用法及类型转换警告解决
MDQuery排序比较块的正确实现方式
你遇到的警告是因为MDQuerySetSortComparatorBlock的回调参数类型并非直接的Date,而是UnsafePointer<Unmanaged<AnyObject>?>?,直接强制转换为Date必然失败。以下是正确的写法:
MDQuerySetSortComparatorBlock(query, { (obj1Ptr, obj2Ptr, context) -> CFComparisonResult in // 1. 解包指针并取出Unmanaged对象 guard let obj1Unmanaged = obj1Ptr?.pointee, let obj2Unmanaged = obj2Ptr?.pointee else { return .compareEqualTo } // 2. 获取对象值(使用takeUnretainedValue,因为MDQuery仍持有对象引用) let obj1 = obj1Unmanaged.takeUnretainedValue() let obj2 = obj2Unmanaged.takeUnretainedValue() // 3. 转换为Date并比较 guard let date1 = obj1 as? Date, let date2 = obj2 as? Date else { return .compareEqualTo } return date1.compare(date2) })
关键说明:
- 指针解包:回调的前两个参数是指向
Unmanaged<AnyObject>?的指针,需要先通过pointee取出内部的Unmanaged对象。 - Unmanaged处理:使用
takeUnretainedValue()而非takeRetainedValue(),因为MDQuery本身维护着这些元数据对象的引用,调用takeRetainedValue()会导致额外的引用计数操作,可能引发内存泄漏。 - 类型安全转换:先将取出的对象转换为
Date,再调用compare(_:)方法直接返回标准的CFComparisonResult,比手动判断更简洁可靠。
替换原代码中的比较块后,警告会消失,排序逻辑也能正常工作。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

