在 Swift 中使用 CFNotificationCallback,或者在 Swift 中使用 @convention(c) 块 [英] Using CFNotificationCallback in Swift, or, @convention(c) blocks in Swift
问题描述
我正在尝试使用(现在是私有的)CTTelephonyCenterAddObserver
C 函数和 CFNotificationCallback
回调块来收听 CoreTelephony 通知.
我的桥接头(用于外部私有 C 函数):
#include #if __cplusplus外部C"{#万一#pragma mark - API/* 这个 API 是对 CFNotificationCenter 的模仿.*/CFNotificationCenterRef CTTelephonyCenterGetDefault();void CTTelephonyCenterAddObserver(CFNotificationCenterRef center, const void *observer, CFNotificationCallback callBack, CFStringRef name, const void *object, CFNotificationSuspensionBehavior pauseBehavior);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 - 定义/* 用于 CoreTelephony 通知系统.*/extern CFStringRef kCTIndicatorsSignalStrengthNotification;#if __cplusplus}#万一
我的 Swift 代码:
let callback: CFNotificationCallback = { (center: CFNotificationCenter?, Observer: UnsafeRawPointer?, name: CFString?, object: UnsafeRawPointer?, info: CFDictionary?) ->作废//...}CTTelephonyCenterAddObserver(CTTelephonyCenterGetDefault().takeUnretainedValue(), nil, callback, kCTIndicatorsSignalStrengthNotification.takeUnretainedValue(), nil, .coalesce)
但是,我无法获得 completion
变量的签名来匹配 CFNotificationCallback
类型别名的要求.
无法转换类型的值'(CFNotificationCenter?,UnsafeRawPointer?,CFString?,UnsafeRawPointer?,CFDictionary?)->空白'到指定类型'CFNotificationCallback'(又名'@convention(c) (Optional<CFNotificationCenter>, Optional<UnsafeMutableRawPointer>, Optional<CFNotificationName>, Optional<UnsafeRawPointer>, Optional<CFDictionary>)'-)
我怎样才能让 @convention(c)
闭包在 Swift 中很好地发挥作用?
让编译器推断闭包的签名工作正常:
let callback: CFNotificationCallback = { center,observer, name, object, info in//工作正常}
尝试在闭包的声明中指定 @convention(c)
会出现错误:
let callback: CFNotificationCallback = { @convention(c) (center: CFNotificationCenter?, Observer: UnsafeRawPointer?, name: CFString?, object: UnsafeRawPointer?, info: CFDictionary?) ->作废//属性只能应用于类型,不能应用于声明.}
似乎发生的事情是,当您手动声明闭包的类型时,它会强制编译器使用该确切类型.但这在技术上是一个闭包声明而不是类型声明,所以 @convention
属性是不允许的.当编译器被允许推断闭包的类型(从它被存储的变量的类型)时,它也可以推断属性.
I am trying to listen to CoreTelephony notifications using the (now private) CTTelephonyCenterAddObserver
C function and CFNotificationCallback
callback blocks.
My bridging header (to extern the private C functions):
#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
My Swift code:
let callback: CFNotificationCallback = { (center: CFNotificationCenter?, observer: UnsafeRawPointer?, name: CFString?, object: UnsafeRawPointer?, info: CFDictionary?) -> Void in
// ...
}
CTTelephonyCenterAddObserver(CTTelephonyCenterGetDefault().takeUnretainedValue(), nil, callback, kCTIndicatorsSignalStrengthNotification.takeUnretainedValue(), nil, .coalesce)
However, I can't get the signature of my completion
variable to match the requirements of the CFNotificationCallback
typealias.
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>) -> ()')
How can I get @convention(c)
closures to play nicely in Swift?
Letting the compiler infer the closure's signature works fine:
let callback: CFNotificationCallback = { center, observer, name, object, info in
//works fine
}
Trying to specify @convention(c)
in the closure's declaration gives an error:
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.
}
It seems like what's going on is that when you manually declare the closure's type, it forces the compiler to use that exact type. But that's technically a closure declaration and not a type declaration, so the @convention
attribute isn't allowed. When the compiler is allowed to infer the closure's type (from the type of the variable it is being stored in), it can infer the attribute too.
这篇关于在 Swift 中使用 CFNotificationCallback,或者在 Swift 中使用 @convention(c) 块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!