在Swift中使用CFNotificationCallback,或在Swift中使用@convention(c)块

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

我的桥接头(外部私有C函数):

 #include  #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 typealias的要求。

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

如何让@convention(c)闭包在Swift中很好地玩?

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

 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属性。 当允许编译器推断闭包的类型时(根据它所存储的变量的类型),它也可以推断出属性。