在Swift中使用CFNotificationCallback或在Swift中使用@convention(c)块 [英] Using CFNotificationCallback in Swift, or, @convention(c) blocks in Swift

查看:350
本文介绍了在Swift中使用CFNotificationCallback或在Swift中使用@convention(c)块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用(现在是私有的)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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆