在 Swift 中使用 CFNotificationCallback,或者在 Swift 中使用 @convention(c) 块
Using CFNotificationCallback in Swift, or, @convention(c) blocks in Swift
我正在尝试使用(现在私有的)CTTelephonyCenterAddObserver
C 函数和 CFNotificationCallback
回调块来收听 CoreTelephony 通知。
我的桥接 header(外部私有 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 中正常运行?
让编译器推断闭包的签名工作正常:
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
属性是不允许的。当允许编译器推断闭包的类型(从存储它的变量的类型)时,它也可以推断属性。
我正在尝试使用(现在私有的)CTTelephonyCenterAddObserver
C 函数和 CFNotificationCallback
回调块来收听 CoreTelephony 通知。
我的桥接 header(外部私有 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 中正常运行?
让编译器推断闭包的签名工作正常:
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
属性是不允许的。当允许编译器推断闭包的类型(从存储它的变量的类型)时,它也可以推断属性。