在Swift中使用CFNotificationCallback或在Swift中使用@convention(c)块 [英] Using CFNotificationCallback in Swift, or, @convention(c) blocks in Swift
问题描述
我正在尝试使用(现在是私有的)CTTelephonyCenterAddObserver
C函数和CFNotificationCallback
回调块来监听CoreTelephony通知.
I am trying to listen to CoreTelephony notifications using the (now private) CTTelephonyCenterAddObserver
C function and CFNotificationCallback
callback blocks.
我的桥接头(用于终止私有C函数):
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
我的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
类型别名的要求.
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>) -> ()')
我怎样才能使@convention(c)
闭包在Swift中正常播放?
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
}
尝试在闭包的声明中指定@convention(c)
会导致错误:
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.
}
似乎正在发生的事情是,当您手动声明闭包的类型时,它会强制编译器使用该确切类型.但这从技术上讲是一个闭包声明,而不是类型声明,因此不允许使用@convention
属性.当允许编译器从其存储的变量的类型推断出闭包的类型时,它也可以推断出该属性.
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屋!