【问题标题】:Using CFNotificationCallback in Swift, or, @convention(c) blocks in Swift在 Swift 中使用 CFNotificationCallback,或者在 Swift 中使用 @convention(c) 块
【发布时间】:2017-03-01 16:49:10
【问题描述】:

我正在尝试使用(现在是私有的)CTTelephonyCenterAddObserver C 函数和 CFNotificationCallback 回调块来收听 CoreTelephony 通知。

我的桥接头(用于外部 C 函数):

#include <CoreFoundation/CoreFoundation.h>

#if __cplusplus
extern "C" {
#endif

#pragma mark - API

    /* This API is a mimic of CFNotificationCenter. */

    CFNotificationCenterRef CTTelephonyCenterGetDefault();
    void CTTelephonyCenterAddObserver(CFNotificationCenterRef center, const void *observer, CFNotificationCallback callBack, CFStringRef name, const void *object, CFNotificationSuspensionBehavior suspensionBehavior);
    void CTTelephonyCenterRemoveObserver(CFNotificationCenterRef center, const void *observer, CFStringRef name, const void *object);
    void CTTelephonyCenterRemoveEveryObserver(CFNotificationCenterRef center, const void *observer);

    void CTIndicatorsGetSignalStrength(long int *raw, long int *graded, long int *bars);

#pragma mark - Definitions

    /* For use with the CoreTelephony notification system. */
    extern CFStringRef kCTIndicatorsSignalStrengthNotification;

#if __cplusplus
}
#endif

我的 Swift 代码:

let callback: CFNotificationCallback = { (center: CFNotificationCenter?, observer: UnsafeRawPointer?, name: CFString?, object: UnsafeRawPointer?, info: CFDictionary?) -> Void in
    // ...
}

CTTelephonyCenterAddObserver(CTTelephonyCenterGetDefault().takeUnretainedValue(), nil, callback, kCTIndicatorsSignalStrengthNotification.takeUnretainedValue(), nil, .coalesce)

但是,我无法获得 completion 变量的签名来匹配 CFNotificationCallback 类型别名的要求。

Cannot convert value of type
'(CFNotificationCenter?, UnsafeRawPointer?, CFString?, UnsafeRawPointer?, CFDictionary?) -> Void'
to specified type
'CFNotificationCallback' (aka '@convention(c) (Optional<CFNotificationCenter>, Optional<UnsafeMutableRawPointer>, Optional<CFNotificationName>, Optional<UnsafeRawPointer>, Optional<CFDictionary>) -> ()')

如何让@convention(c) 闭包在 Swift 中发挥出色?

【问题讨论】:

  • 它无法编译,因为observerUnsafeMutableRawPointer,而不是UnsafeRawPointer

标签: c swift swift3 core-telephony cfnotification


【解决方案1】:

让编译器推断闭包的签名可以正常工作:

let callback: CFNotificationCallback = { center, observer, name, object, info in
    //works fine
}

试图在闭包声明中指定@convention(c) 会报错:

let callback: CFNotificationCallback = { @convention(c) (center: CFNotificationCenter?, observer: UnsafeRawPointer?, name: CFString?, object: UnsafeRawPointer?, info: CFDictionary?) -> Void in
    //Attribute can only be applied to types, not declarations.
}

似乎正在发生的事情是,当您手动声明闭包的类型时,它会强制编译器使用该确切类型。但从技术上讲,这是一个闭包声明而不是类型声明,因此不允许使用 @convention 属性。当允许编译器推断闭包的类型时(从它存储的变量的类型),它也可以推断出属性。

【讨论】:

  • 啊,确实如此,我把事情复杂化了。谢谢!
猜你喜欢
  • 1970-01-01
  • 2017-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-26
相关资源
最近更新 更多