You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 15:30:58